CodeForces:643(VK cup)

前言

毒瘤比赛,三紫二黑(而且感觉G完全有黑的难度)
也受到了下午统练的影响,做了一天qwq
AB很水,CD不错,EFG直接贺
也与我
A奇水
B是可以五分钟做一做的简单构造
C是小清新dp,可以斜优我不想动脑直接分治挂log
D思路不太难想,但写起来是真的恶心
E是标准CF那种令人哭笑不得的“…时…,所以只需要考虑”题,但是dp思想还是不错的
F是诡异的组合题,先找到答案上界再试图证明可以达到
G需要一个前置的小结论,然而我并不会。。。后面线段树快速合并区间的地方也不是很好想

CF643A Bear and Colors

Description\text{Description}Description

Limak 有 nnn 个球,从左到右编号依次为 1…n1 \dots n1n。同时又有 nnn 种颜色,从编号依次为 1…n1 \dots n1n。第 iii 个球的编号为 tit_iti

对于球中每一个固定的段(含有连续元素的集合),可以定义一个主要颜色,即此段中出现次数最多的颜色。在可以有多种主要颜色的情况下,选择编号最小的。

现有 n(n+1)2\dfrac{n(n + 1)}{2}2n(n+1) 个不为空的段。对于每个颜色,你需要输出此颜色作为主要颜色的次数。

n≤5000n\le 5000n5000

Solution\text{Solution}Solution

本来还觉得可能得想想,看到数据范围笑了。
直接开桶 n2n^2n2 暴力扫一遍即可。

Description\text{Description}Description

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=5050;
#define ll long long
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m;
int bac[N],a[N],res,ans[N];
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();for(int i=1;i<=n;i++) a[i]=read();for(int l=1;l<=n;l++){memset(bac,0,sizeof(bac));for(int r=l;r<=n;r++){int o=a[r];++bac[o];if(bac[o]>bac[res]||(bac[o]==bac[res]&&o<res)) res=o;ans[res]++;}}for(int i=1;i<=n;i++) printf("%d ",ans[i]);return 0;
}
/*
*/

CF643B Bear and Two Paths

Description\text{Description}Description

一共有 nnn 个结点,给出互异的四个点 a,b,c,da,b,c,da,b,c,d,请你构造一个边数不超过 kkk 的无向图,使得 aaabbbcccddd 之间都存在一条哈密尔顿路径,且 a,ba,ba,b 之间和 c,dc,dc,d 之间不能直接连通。
请输出你构造的路径。
4≤n≤10004\le n\le 10004n1000

Solution\text{Solution}Solution

首先,对于 n=4n=4n=4 的情况,显然无解。
否则,只要找到一种用边最少的方案即可。
手玩发现,可以通过构造 a→c→x→...→y→d→ba\to c\to x\to...\to y\to d\to bacx...ydb,再加两条 a→xa\to xaxy→by\to byb 的边满足要求,总边数是 n+1n+1n+1
由于从 ccc 走一定要去往 a,ba,ba,b,这都需要加边跳,所以至少加两条边,答案不会少于这个了。
问题得以解决。

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=5050;
#define ll long long
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m;
int x[N],a,b,c,d,vis[N];
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();m=read();a=read();b=read();c=read();d=read();if(n<=4||m<n+1){printf("-1");return 0;}x[1]=a;x[n]=b;x[2]=c;x[n-1]=d;vis[a]=vis[b]=vis[c]=vis[d]=1;int tot=2;for(int i=1;i<=n;i++){if(!vis[i]) x[++tot]=i;}for(int i=1;i<=n;i++) printf("%d ",x[i]);putchar('\n');printf("%d %d ",c,a);for(int i=3;i<=n-2;i++) printf("%d ",x[i]);printf("%d %d\n",b,d);return 0;
}
/*
*/

CF643C Levels and Regions

Description\text{Description}Description

有一种电子游戏,它由 nnn 个关卡组成,每个关卡都被赋予了一个值 tit_iti

现在,你要将这些关卡分成 kkk 个级别,每个级别 jjj 对应了一段连续的关卡 [lj,rj][l_j,r_j][lj,rj],且必有 lj≤rjl_j\leq r_jljrj。任何一个关卡在且仅在一个级别中。

然后,一名玩家将会从第 111 个关卡,按顺序一直刷到第 nnn 个关卡。当他打到第 iii 个关卡时,设这个关卡所在的级别是 jjj,则他有 ti∑x=ljitx\dfrac{t_i}{\sum\limits_{x=l_j}^{i}t_x}x=ljitxti 的概率在111小时内AC这个关卡,然后进入下一关;或者没有 AC 这个关卡(但仍然花了 111 小时),还得再次挑战这个关卡。

你需要找到一种划分方法,使得该玩家期望 AK 该游戏的期望时间最小。输出这个最小的期望时间。

Solution\text{Solution}Solution

一道乍看很吓人但是仔细想想并不难的小清新 dp 题。
有一个期望相关的常用结论:若一件事做成的概率是 ppp,那么做成这件事需要的期望次数是 1p\dfrac{1}{p}p1
证明:设期望次数为 xxx,讨论第一次做成或者没做成,就有:
x=(p×0+(1−p)×x)+1x=(p\times0+(1-p)\times x)+1x=(p×0+(1p)×x)+1
移项即可得。

回到本题。
显然不同段之间互相独立。
sumi=∑j=1itjsum_i=\sum_{j=1}^i t_jsumi=j=1itj
那么本题 (l,r)(l,r)(l,r) 区间划分成一段完成的期望次数就是:
∑i=lrsumi−suml−1ti\sum_{i=l}^r \frac{sum_i-sum_{l-1}}{t_i}i=lrtisumisuml1
也就是:
∑i=lrsumiti−suml−1×∑i=lr1ti\sum_{i=l}^r \frac{sum_i}{t_i}-sum_{l-1}\times\sum_{i=l}^r \frac{1}{t_i}i=lrtisumisuml1×i=lrti1
∑i=lrsumiti\sum_{i=l}^r \dfrac{sum_i}{t_i}i=lrtisumi∑i=lr1ti\sum_{i=l}^r \dfrac{1}{t_i}i=lrti1 分别求前缀和,我们就可以 O(1)O(1)O(1) 转移了。
然后直观感受可以发现,这个东西是满足决策单调性的。
感性理解一下就是要使全局尽可能小,前面的 ∑i=lrsumiti\sum_{i=l}^r \dfrac{sum_i}{t_i}i=lrtisumi 全合起来后是定值,后面多一个元素的时候,∑i=lr1ti\sum_{i=l}^r \dfrac{1}{t_i}i=lrti1 变大,那么为了多减一些,suml−1sum_{l-1}suml1 的值应该相应的变大(或者至少不应该变小),所以转移点有单调性的。
直接上分治即可,时间复杂度 O(nklog⁡n)O(nk\log n)O(nklogn)
(看题解的大佬这题也可以斜优做把 log 去掉)

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=2e5+100;
#define ll long long
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m;
double sum[N],t[N];
double s1[N],s2[N];
inline double calc(int l,int r){return (s1[r]-s1[l-1])-sum[l-1]*(s2[r]-s2[l-1]);
}
double dp[52][N];
void solve(int k,int l,int r,int tl,int tr){if(l>r) return;int mid=(l+r)>>1,pl(0);for(int i=tl;i<=min(mid-1,tr);i++){double w=dp[k-1][i]+calc(i+1,mid);if(w<dp[k][mid]){dp[k][mid]=w;pl=i;}}solve(k,l,mid-1,tl,pl);solve(k,mid+1,r,pl,tr);return;
}
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();m=read();for(int i=1;i<=n;i++){t[i]=read();sum[i]=sum[i-1]+t[i];s1[i]=s1[i-1]+sum[i]/t[i];s2[i]=s2[i-1]+1.0/t[i];}for(int i=0;i<=m;i++){for(int j=0;j<=n;j++) dp[i][j]=2e18;}dp[0][0]=0;for(int k=1;k<=m;k++) solve(k,1,n,0,n-1);printf("%lf\n",dp[m][n]);return 0;
}
/**/

CF643D Bearish Fanpages

Description\text{Description}Description

给定一个 nnn 个点的基环内向树森林,即给定每个点 iii 的后继 fif_ifi
特别地,保证在任意时刻,这个基环内向森林中的环长都 ≥3\boldsymbol{\ge 3}3

在这个限制下,考虑与某个点 iii 距离不超过 111 的点,也就是 iii 本身,iii 的后继 fif_ifi 以及若干个后继为 iii 的点。
不妨假设有 kkk 个点的后继为 iii,则我们需要考虑这 k+2k + 2k+2 个点(这是因为环长 ≥3\ge 33,不会出现重复的点)。
称这 k+2k + 2k+2 个点分别为 i,j0,j1,j2,…,jki, j_0, j_1, j_2, \ldots , j_ki,j0,j1,j2,,jkj0j_0j0iii 的后继,j1…kj_{1 \ldots k}j1k 为后继为 iii 的那 kkk 个点)。

现在假设神秘事件发生了,每个点都会进入一些人,第 iii 个点会进入 tit_iti 个人。
恰好 ⌊tik+2⌋\left\lfloor \frac{t_i}{k+2} \right\rfloork+2ti 个人会进入 j0,j1,j2,…,jkj_0, j_1, j_2, \ldots , j_kj0,j1,j2,,jk 号点(每个点都进入 ⌊tik+2⌋\left\lfloor \frac{t_i}{k+2} \right\rfloork+2ti 个人),剩下的 ti−(k+1)⋅⁣⌊tik+2⌋t_i - (k + 1) \cdot \!\left\lfloor \frac{t_i}{k+2} \right\rfloorti(k+1)k+2ti 个人会留在点 iii

你需要依次处理 qqq 个操作:

1 i j:将 fif_ifi 改为 jjj,即把 iii 的后继变成 jjj。保证仍然满足上文中的条件。
2 i:计算当神秘事件发生时,第 iii 个点最终会留下多少人。
3:计算当神秘事件发生时,每个点内最终留下的人数的最小值和最大值。

注意:每次神秘事件发生都是互不影响的。

Solution\text{Solution}Solution

阴间大模拟题。
容易想到,问题可以转化成对亿些集合的集体修改和亿些单点的修改。
全局 min⁡,max⁡\min,\maxmin,max 开两个 set 维护即可。
集体修改考虑懒标记,我用的是线段树维护,对于每个点开一棵以它为父亲的线段树,动态开点插入删除修改瞎做即可。

Code\text{Code}Code

有的地方为了可读性忽略了代码效率,自带 242424 倍常数,成功斩获最劣解
极其屎山,不过看几篇题解似乎都差不多…

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=1e5+100;
#define ll long long
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m,tim;
ll t[N],w[N],v[N];
int du[N],fa[N];
multiset<ll>mn,mx;#define mid ((l+r)>>1)
struct tree{int ls,rs;ll mn,mx,laz;
}tr[N<<6];
int rt[N],tot;
inline int New(){++tim;++tot;tr[tot].mn=2e18;tr[tot].mx=-2e18;return tot;
}
inline void pushup(int k){++tim;tr[k].mn=min(tr[tr[k].ls].mn,tr[tr[k].rs].mn);tr[k].mx=max(tr[tr[k].ls].mx,tr[tr[k].rs].mx);return;
}
inline void tag(int k,ll v){++tim;if(!k) return;tr[k].laz+=v;tr[k].mn+=v;tr[k].mx+=v;return;
}
inline void pushdown(int k){++tim;ll o=tr[k].laz;tr[k].laz=0;if(!o) return;tag(tr[k].ls,o);tag(tr[k].rs,o);return;
}
void add(int &k,int l,int r,int p,ll v){++tim;if(!k) k=New();if(l==r){tr[k].mn=tr[k].mx=v;return;}pushdown(k);if(p<=mid) add(tr[k].ls,l,mid,p,v);else add(tr[k].rs,mid+1,r,p,v);pushup(k);
}
ll ask(int k,int l,int r,int p,int op=0){++tim;assert(k);if(l==r){ll res=tr[k].mn;if(op) tr[k].mx=-2e18,tr[k].mn=2e18;return res;}pushdown(k);ll res(0);if(p<=mid) res=ask(tr[k].ls,l,mid,p,op);else res=ask(tr[k].rs,mid+1,r,p,op);pushup(k);return res;
}
void change(int k,int l,int r,int p,ll v){++tim;assert(k);if(l==r){tr[k].mn+=v;tr[k].mx+=v;return;}pushdown(k);if(p<=mid) change(tr[k].ls,l,mid,p,v);else change(tr[k].rs,mid+1,r,p,v);pushup(k);return;
}
void upd(int x,ll w){++tim;change(rt[fa[x]],1,n,x,w);return;
}set<int>s;
ll sef[N];
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endiftr[0].mn=2e18;tr[0].mx=-2e18;n=read();m=read();for(int i=1;i<=n;i++) t[i]=read();for(int i=1;i<=n;i++) du[i]=2;for(int i=1;i<=n;i++){fa[i]=read();du[fa[i]]++;}for(int i=1;i<=n;i++) w[i]=t[i]/du[i];for(int i=1;i<=n;i++) v[fa[i]]+=w[i];for(int i=1;i<=n;i++){ll val=v[i]+w[fa[i]]+t[i]-w[i]*(du[i]-1);sef[i]=t[i]-w[i]*(du[i]-1);//debug("i=%d val=%lld v=%lld w=%lld du\n",i,val);add(rt[fa[i]],1,n,i,val);}for(int i=1;i<=n;i++){mn.insert(tr[rt[i]].mn);mx.insert(tr[rt[i]].mx);}for(int i=1;i<=m;i++){int op=read();if(op==1){int x=read(),y=read(),f=fa[x];fa[x]=y;//debug("erase: f:(%lld %lld) y:(%lld %lld)\n",//    tr[rt[f]].mn,tr[rt[f]].mx,tr[rt[y]].mn,tr[rt[y]].mx);s.insert(y);s.insert(f);s.insert(fa[y]);s.insert(fa[f]);s.insert(fa[fa[y]]);s.insert(fa[fa[f]]);for(int now:s){mn.erase(mn.find(tr[rt[now]].mn));mx.erase(mx.find(tr[rt[now]].mx));}ll val=ask(rt[f],1,n,x,1);val-=w[f];tag(rt[f],-w[f]);upd(fa[f],-w[f]);upd(f,-sef[f]);du[f]--;w[f]=t[f]/du[f];sef[f]=t[f]-w[f]*(du[f]-1);tag(rt[f],w[f]);upd(fa[f],w[f]);upd(f,sef[f]);tag(rt[y],-w[y]);upd(fa[y],-w[y]);upd(y,-sef[y]);du[y]++;w[y]=t[y]/du[y];sef[y]=t[y]-w[y]*(du[y]-1);tag(rt[y],w[y]);upd(fa[y],w[y]);upd(y,sef[y]);upd(f,-w[x]);upd(y,w[x]);val+=w[y];add(rt[y],1,n,x,val);for(int now:s){//if(n==20000) break;mn.insert(tr[rt[now]].mn);mx.insert(tr[rt[now]].mx);}      //debug("insert: f:(%lld %lld) y:(%lld %lld)\n",//    tr[rt[f]].mn,tr[rt[f]].mx,tr[rt[y]].mn,tr[rt[y]].mx);}else if(op==2){int x=read();//if(n<20000)printf("%lld\n",ask(rt[fa[x]],1,n,x));}else{//if(n<20000)printf("%lld %lld\n",(*mn.begin()),(*mx.rbegin()));}//if(n>=20000) printf("i=%d tot=%d\n",i,tot);//if(i%100==0){//printf("i=%d tot=%d time=%lf calc=%d\n",i,tot,1.0*clock()/CLOCKS_PER_SEC,tim);//}//if(1.0*clock()/CLOCKS_PER_SEC>4.9){//printf("i=%d tot=%d\n",i,tot);break;//}s.clear();}return 0;
}
/**/

CF643E Bear and Destroying Subtrees

Description\text{Description}Description

给你一棵初始只有根为 111 的树。

共有 qqq 次操作。

1 x表示加入一个以 xxx 为父亲的新点。

2 x表示求以 xxx 为根的子树期望最深深度。

每条边都有 12\dfrac{1}{2}21 的概率断裂。

1≤q≤5×1051\leq q\leq 5\times 10^51q5×105

Solution\text{Solution}Solution

这题很 CF…
注意到,当链很长的时候不被断开的概率是极低的。
具体的,当链长超过 606060,对答案的影响完全可以忽略不计。
(经过实测,其实只考虑到 404040 都是没问题的。

这样本题就好办多了。
但依然没有显然。
由于本来答案取 max⁡\maxmax 的性质,设计 dpx,idp_{x,i}dpx,i 表示子树内答案小于等于 iii 的概率。
那么就有转移:
dpfa,k+1=∏12×(dpson,k+1)dp_{fa,k+1}=\prod \frac{1}{2}\times (dp_{son,k}+1)dpfa,k+1=21×(dpson,k+1)

每次加新点对 606060 个祖先都只会改一层的 dp,所以直接暴力修改即可。

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=5e5+100;
#define ll long long
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m,tim;
double dp[N][62];
int fa[N],tot=1,o=60;
void remove(int x,int k){if(!fa[x]||k>=o||!x) return;remove(fa[x],k+1);dp[fa[x]][k+1]/=(0.5*(dp[x][k]+1));return;
}
void upd(int x,int k){if(!fa[x]||k>=o||!x) return;dp[fa[x]][k+1]*=0.5*(dp[x][k]+1);//printf("fa=%d *=%lf\n",fa[x],0.5*(dp[x][k]+1));upd(fa[x],k+1);
}
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();for(int i=1;i<=o;i++) dp[1][i]=1;for(int i=1;i<=n;i++){int op=read(),x=read();if(op==1){fa[++tot]=x;x=tot;for(int j=1;j<=o;j++) dp[x][j]=1;remove(fa[x],1);upd(x,0);}else{double ans=o-1;for(int i=1;i<o;i++) ans-=dp[x][i];printf("%.10lf\n",ans);}}return 0;
}
/**/

CF643F Bears and Juice

Description\text{Description}Description

nnn 只熊和若干桶果汁和恰好一桶酒,每一天每只熊会选择一些桶(可能不选)并各喝一 杯,喝到酒的熊会去睡觉并不再回来,通过这个信息,熊们想知道哪个桶里是酒。

只有 ppp 个睡 觉的位置,当睡觉的熊超过了 ppp 只或者所有熊都在睡觉时熊们就失败了。

RiR_iRi 表示在 iii 天内桶的数量最多少,使得熊可以成功知道酒的位置。令 Xi=(i×Ri)mod232X_i = (i\times R_i) \bmod 2^{32}Xi=(i×Ri)mod232,你需要求出 X1⊕X2⊕…⊕XqX_1 \oplus X_2 \oplus\ldots \oplus X_qX1X2Xq

1≤n≤1091\leq n\leq 10^91n1091≤p≤1301\leq p\leq 1301p1301≤q≤2×1061\leq q \leq 2\times 10^61q2×106

Solution\text{Solution}Solution

魔法操作。
考虑答案的上界,就是所有熊的反应的不同方案数
对于 iii 天,这个数量就是:
fi=∑j=0min⁡(n−1,p)Cnj×ijf_i=\sum_{j=0}^{\min(n-1,p)} C_n^j\times i^jfi=j=0min(n1,p)Cnj×ij
jjj 枚举喝醉的熊的数量,CnjC_n^jCnj 是从 nnn 头里选 jjj 头,每头可以从 iii 天中选一天喝醉。
然后可以发现,这个上界是可以构造出方案卡到的。
所以答案就是这个。
实现上,由于 nnn 过大,不便求 CnjC_n^jCnj,可以暴力约分来做。

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=5e5+100;
#define ll long long
#define ui unsigned int
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,p,q;
ui a[150],b[150];
ui c[150];
ui gcd(ui a,ui b){return b?gcd(b,a%b):a;}
void init(){for(int i=0;i<=min(p,n-1);i++){for(int j=1;j<=i;j++) a[j]=j,b[j]=n-j+1;for(int j=1;j<=i;j++){for(int k=1;k<=i;k++){int g=gcd(a[j],b[k]);a[j]/=g;b[k]/=g;}assert(a[j]==1);}c[i]=1;for(int j=1;j<=i;j++) c[i]*=b[j];}return;
}
inline ui ksm(ui x,ui k){ui res(1);while(k){if(k&1) res*=x;x=x*x;k>>=1;}return res;
}
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();p=read();q=read();init();ui ans(0);for(int i=1;i<=q;i++){ui base(1),res(0);for(int j=0;j<=min(n-1,p);j++){res+=c[j]*base;base*=i;}ans^=(i*res);}printf("%u\n",ans);return 0;
}
/**/

CF643G Choosing Ads

Description\text{Description}Description

给定一个长度为 nnn 的序列和一个整数 ppp

  • mmm 个操作,操作要么是区间赋值,要么是询问区间内出现次数至少占 p%p\%p% 的数。
  • 输出询问的答案时,可以包含错的数,也可以重复输出,但对的数一定要在答案中,且输出的数的个数不超过 ⌊100p⌋\lfloor \dfrac{100}{p} \rfloorp100
  • n,m≤1.5×105n,m \le 1.5 \times 10^5n,m1.5×10520≤p≤10020 \le p \le 10020p100

Solution\text{Solution}Solution

魔法操作。
考虑 p>50p>50p>50 (严格众数)时如何做。
每次删去两个不同的数,直到删到剩下的种类不超过一种时,如果有严格众数,显然会剩到最后。

类似的,推广到 p≥20p\ge 20p20 的情况。令 k=⌊100p⌋k=\lfloor \dfrac{100}{p}\rfloork=p100,每次删去 k+1k+1k+1 个不同的数,直到不能删为止,也易证如果有符合条件的数最后一定会剩下。
现在要对于区间询问快速模拟这个过程,使用线段树即可,每次暴力 O(k2)O(k^2)O(k2) 暴力合并区间,具体实现建议观看代码。

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=2e5+100;
#define ll long long
#define ui unsigned int
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,k,m;struct node{int val[6],num[6],tot;
}tr[N<<2];
node operator + (const node &a,const node &b){node res=a;for(int i=1;i<=b.tot;i++){bool jd(0);for(int j=1;j<=res.tot;j++){if(res.val[j]==b.val[i]){jd=1;res.num[j]+=b.num[i];break;}}if(jd) continue;if(res.tot<k){++res.tot;res.val[res.tot]=b.val[i];res.num[res.tot]=b.num[i];continue;}int pl(1);for(int j=2;j<=res.tot;j++){if(res.num[j]<res.num[pl]) pl=j;}if(res.num[pl]>b.num[i]){for(int j=1;j<=res.tot;j++) res.num[j]-=b.num[i];}else{int o=res.num[pl];res.num[pl]=b.num[i];res.val[pl]=b.val[i];for(int j=1;j<=res.tot;j++) res.num[j]-=o;}}return res;
}#define mid ((l+r)>>1)
#define ls (k<<1)
#define rs (k<<1|1)
int laz[N<<2];
inline void pushup(int k){tr[k]=tr[ls]+tr[rs];}
inline void tag(int k,int l,int r,int v){laz[k]=v;tr[k].tot=1;tr[k].num[1]=r-l+1;tr[k].val[1]=v;return;
}
inline void pushdown(int k,int l,int r){int o=laz[k];laz[k]=0;if(!o) return;tag(ls,l,mid,o);tag(rs,mid+1,r,o);return;
}
inline void change(int k,int l,int r,int x,int y,int v){if(x<=l&&r<=y){tag(k,l,r,v);return;}pushdown(k,l,r);if(x<=mid) change(ls,l,mid,x,y,v);if(y>mid) change(rs,mid+1,r,x,y,v);pushup(k);
}
node ask(int k,int l,int r,int x,int y){  if(x<=l&&r<=y) return tr[k];pushdown(k,l,r);if(y<=mid) return ask(ls,l,mid,x,y);else if(x>mid) return ask(rs,mid+1,r,x,y);else{node a=ask(ls,l,mid,x,y),b=ask(rs,mid+1,r,x,y);return a+b;}
}
int a[N];
void build(int k,int l,int r){if(l==r){tr[k].tot=1;tr[k].num[1]=1;tr[k].val[1]=a[l];return;}build(ls,l,mid);build(rs,mid+1,r);pushup(k);
}signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();m=read();k=100/read();for(int i=1;i<=n;i++) a[i]=read();build(1,1,n);for(int i=1;i<=m;i++){int op=read(),l=read(),r=read();if(op==1){int x=read();change(1,1,n,l,r,x);}else{node res=ask(1,1,n,l,r);printf("%d ",res.tot);for(int j=1;j<=res.tot;j++) printf("%d ",res.val[j]);putchar('\n');}}return 0;
}
/*
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317234.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一二三系列之优先队列、st表——Battle,Heapsort,A Magic Lamp

文章目录BattleHeapsortA Magic LampBattle source 如果怪兽先死&#xff0c;那么英雄血量不足也没关系 反悔贪心 每次都先杀怪兽再说&#xff0c;如果血量不够了&#xff0c;就倒回去从怪兽打出伤害由高到低反悔&#xff0c;选择抵御或者加血&#xff0c;肯定哪个加的更多…

JavaWeb --第三章 HTTP协议详解

JavaWeb --第三章 HTTP协议详解 Http 什么是HTTP HTTP&#xff1a; 超文本传输协议&#xff08;Hypertext Transfer Protocol&#xff0c;HTTP&#xff09;是一个简单的请求-响应协议&#xff0c;它通常运行在TCP之上。 文本&#xff1a;html&#xff0c;字符串&#xff0c…

AT2382-[AGC015D]A or...or B Problem

正题 题目链接:https://www.luogu.com.cn/problem/AT2382 题目大意 询问在[L,R][L,R][L,R]中选取一个或多个数&#xff0c;将它们按位或后能得到多少种不同的结果。 1≤L≤R<2601\leq L\leq R<2^{60}1≤L≤R<260 解题思路 我们先把高位的LLL和RRR都有的111都删除&a…

数据结构一【树状数组】普通、二维、离线树状数组的(单点修改,单点查询,区间修改,区间查询)模板及应用例题总结

文章目录树状数组lowbit线段树与树状数组单点修改区间查询区间修改区间求和二维树状数组离线树状数组例题POJ&#xff1a;starsMooFest[SDOI2009]HH的项链Turing TreeCounting SequencesZip-line树状数组 用于快速高效的计算与前缀和相关的信息 lowbit int lowbit( int i ) …

如何优雅的利用Windows服务来部署ASP.NET Core程序

上一篇文章中我给大家讲述了五种部署ASP.NET Core网站的方法&#xff0c;其中有一种方式是通过Windows服务来进行部署&#xff0c;这样既可以做到开启自启动&#xff0c;又不会因为iis的反向代理而损失部分性能。但是美中不足的是需要借助第三方软件nssm来进行&#xff0c;那么…

JavaWeb --第四章Maven详解

JavaWeb --第四章Maven详解 文章目录MavenMaven架构管理工具下载安装Maven配置环境变量阿里云镜像本地仓库在IDEA中使用Maven创建一个普通的Maven项目在IDEA中标记文件夹功能在IDEA中配置tomcatpom文件IDEA操作解决遇到的问题Maven 为什么要学这个技术&#xff1f; 在javaweb…

P3242 [HNOI2015] 接水果(整体二分、扫描线、dfs序)

解析 一道有点毒瘤的题 也是一道感觉真的可以出现在考场上的很综合的题 做的还可以 除了一开始把盘子和水果看反白写了各树套树之外 为什么盘子是水果的子路径啊 由于是做专题爬过来的多次询问区间第k小&#xff0c;想到整体二分 那么重点就是子路径的判定问题 发现&#xff…

UOJ#748-[UNR #6]机器人表演【dp】

正题 题目链接:https://uoj.ac/problem/748 题目大意 有一个长度为nnn的010101序列&#xff0c;然后ttt次插入一个000和一个111&#xff0c;要求000在111前面&#xff0c;求最终能得到多少种本质不同的串。 1≤n,t≤3001\leq n,t\leq 3001≤n,t≤300 解题思路 我们考虑一个n…

夯实基础项目工程之图论——Uncle Bogdan and Country Happiness,Graph Coloring,How Many Paths?,Array Differentiation

文章目录做题情况项目报告Uncle Bogdan and Country HappinessGraph ColoringHow Many Paths?Array Differentiation做题情况项目报告 T1,T3T1,T3T1,T3一眼题&#xff0c;在实现上&#xff0c;T3T3T3耗时略长&#xff08;有些情况未考虑到位&#xff09; T4T4T4感觉题&#xf…

Codeforces Round #716 (Div. 2)

Codeforces Round #716 (Div. 2) CodeForces 1514 题号题目知识点难度APerfectly Imperfect ArrayBAND 0, Sum BigCProduct 1 Modulo NDCut and StickEBaby Ehab’s Hyper Apartment

用StyleCop规范团队代码

前言编码风格&#xff0c;每个人都是有不同的特点&#xff0c;风格各异&#xff0c;而且一个人在不同的时期&#xff0c;编码风格的差异也可能是非常大的&#xff0c;好比学生时代&#xff0c;刚工作的时候&#xff0c;工作一段时间后等。在一个团队中&#xff0c;或一个项目中…

CodeForces:103(div1)104(div2)

文章目录前言CF104A BlackjackDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}CodeCF103A Testing Pants for SadnessDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}CodeCF103B CthulhuDe…

UOJ#749-[UNR #6]稳健型选手【贪心,分治,主席树】

正题 题目链接:https://uoj.ac/problem/749 题目大意 如果有序列aaa&#xff0c;你每次取走一个数字后然后这个序列最前面的数字会被别人取走&#xff0c;直到序列为空。此时f(a)f(a)f(a)表示你最大能取走的权值和。 给出一个长度为nnn的序列aaa&#xff0c;qqq次询问区间[l…

A. And Then There Were K

A. And Then There Were K 题意&#xff1a; 给你一个n&#xff0c;让你求一个k&#xff0c;使得满足下列式子&#xff1a; n & (n-1) & (n-2) &…&(k) 0 问k最小是多少&#xff1f; 题解&#xff1a; 找规律 比如n的二进制为&#xff1a;1111 那么n-1就是…

一键发布部署vs插件[AntDeploy],让net开发者更幸福

一键发布工具(ant deploy tool)插件下载地址&#xff1a;https://marketplace.visualstudio.com/items?itemNamenainaigu.AntDeploy1.iis一键发布自动部署 (iis deploy support)支持netcore 和 netframework发布 (支持mvc webapi)支持website自动创建ps:需要在windows 服务器上…

数据结构二之线段树Ⅰ——Count Color,Hotel,Transformation,Tree Generator™

普通的下标线段树Count ColorHotelTransformationTree Generator™Count Color POJ2777 查询区间内颜色种类数&#xff0c;观察到颜色种类数只有30&#xff0c;完全可以状压成整型存储&#xff0c;没有必要开30棵线段树 区间内有这颜色就置为111&#xff0c;没有这个颜色就是…

计算几何全家桶

文章目录前言精度点/向量相关表示向量基本运算角度相关向量夹角旋转直线/线段相关表示点与线求点到直线垂足求点关于直线的对称点点与直线的位置关系点与直线的距离线与线直线与直线的位置关系共线与垂直判断线段与线段是否相交求直线与直线的交点角平分线中垂线多边形表示求多…

uoj#750-[UNR #6]小火车【二分,折半,鸽笼原理】

正题 题目链接:https://uoj.ac/problem/750 题目大意 给出nnn个数字和一个ppp&#xff0c;保证2n>p2^n> p2n>p。现在要求一个序列www满足wi∈[−1,1]w_i\in[-1,1]wi​∈[−1,1]&#xff0c;使得∑i1nwiai≡0(modp)\sum_{i1}^nw_ia_i\equiv 0\pmod p∑i1n​wi​ai​≡…

Sequence Pair Weight

Sequence Pair Weight 题意&#xff1a; 一个数组a&#xff0c;其中两个一样的数的贡献为1&#xff0c;问这个数组的所有子串的贡献和是多少? 题解&#xff1a; 举例&#xff1a; 对于[1&#xff0c;2&#xff0c;1&#xff0c;2&#xff0c;1&#xff0c;1&#xff0c;4]…

什么是量子计算机?用一个简单例子来解释

译者&#xff1a;王亮 作者&#xff1a;YK Sugi 原文&#xff1a;http://t.cn/EZAElk0Hi&#xff0c;大家好&#xff01;不久前&#xff0c;我参观了加拿大温哥华的D-Wave Systems公司&#xff0c;这是一家制造前沿量子计算机的公司。我在那里学到了很多关于量子计算机的知识&a…