[bzoj4722]由乃
来源:互联网 发布:数据挖掘工程师就业 编辑:程序博客网 时间:2024/06/08 09:09
题目描述
由于一周目的由乃穿越到了三周目,并带来了巨大的影响,改变了三周目所有未来日记所有者的命运所以三周目的
神Deus准备不利用未来日记来决定把神的位置交给谁Deus特别崇拜某知名社会主义国家领导人,因为他的寿命比神
还长,所以他想钦定下一个卡密,而不通过选举他决定钦定三周目的由乃成为卡密,去和一周目的雪辉重逢(终于
做了一件好事了)但是,既然是钦定,那么肯定还是要做做样子的,以防某些来自香港的记者造个大新闻,导致被
批判一番所以Deus决定,出一道OI题来考察由乃有没有当神的能力如果你没有看过这个番,以上内容可以无视
给一个长为n的序列a,每个数在0到v - 1之间,有m次操作。
操作1:每次询问一个区间中是否可以选出两个下标的集合X,Y,满足:
1.X和Y没有交集
2.设集合X中有一个元素是i,则其对集合X的贡献是a[i] + 1,要求集合X的元素的总贡献和集合Y的元素的总贡献
相等如果可以选出这两个集合,输出 Yuno否则输出 Yuki
操作2:修改一个区间l,r之间的数,使得所有l <= i <= r,a[i] = a[i] * a[i] * a[i] % v ,即区间立方
如果你没有看过这个番,或者你已经是国家队队员,以下内容可以无视
可以去和雪辉重逢,由乃肯定非常高兴然而可爱的由乃虽然很机智但是并不会OI呀,特别不会数据结构这种神奇的
东西(会数据结构和成为卡密有什么关系吗233333)所以她请您——未来的国家队队员来帮助她啦
玄学
网上有个结论,1000以内的自然数,如果有那么个至少13个,无论是多少总能通过选择其中一些加减得到0。
感谢帮助……13是这样算的
假设区间中选两个集合和相等则一定可以
集合的方案数是2^len,但是值域是len * 1000
解得13
有了这个结论,区间长度太大的可以直接输出了。
不能直接输出的时候区间长度比较小,可以通过折半搜索搜出来。
至于那个区间修改,我们用线段树维护。
但是次幂tag可能会爆。准确来说模数鬼畜不可能得到次数。
因此考虑倍增
那么有
然后得到新值时将tag二进制拆分然后利用倍增数组即可。
我们的懒标记应该特别懒除非询问叶子不然也不清掉,这样会快些。
#include<cstdio> #include<algorithm>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int maxn=100000+10;int tag[maxn*4],b[maxn],a[maxn],lf[1000+10][20+5];bool bz[10000],leaf[maxn*4];int i,j,k,l,r,mid,t,n,m,mo,top;bool czy;int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return x*f;}void mark(int p,int v){ tag[p]+=v;}void down(int p){ if (tag[p]){ mark(p*2,tag[p]); mark(p*2+1,tag[p]); tag[p]=0; }}void change(int p,int l,int r,int a,int b){ if (l==a&&r==b){ mark(p,1); return; } down(p); int mid=(l+r)/2; if (b<=mid) change(p*2,l,mid,a,b); else if (a>mid) change(p*2+1,mid+1,r,a,b); else change(p*2,l,mid,a,mid),change(p*2+1,mid+1,r,mid+1,b);}int count(int x,int y){ int j=20; while (j>=0){ if (y>=(1<<j)){ x=lf[x][j]; y-=(1<<j); } j--; } return x;}void query(int p,int l,int r,int w){ if (l==r){ a[l]=count(a[l],tag[p]); tag[p]=0; return; } down(p); int mid=(l+r)/2; if (w<=mid) query(p*2,l,mid,w);else query(p*2+1,mid+1,r,w);}void getleaf(int p,int l,int r){ if (l==r){ leaf[p]=1; return; } int mid=(l+r)/2; getleaf(p*2,l,mid);getleaf(p*2+1,mid+1,r);}void dfs1(int x,int y,bool f){ if (x==mid+1){ if (f&&y==0) czy=1; if (f&&y>=0&&!bz[y]){ b[++top]=y; bz[y]=1; } return; } dfs1(x+1,y,f); if (czy) return; dfs1(x+1,y+a[x]+1,1); if (czy) return; dfs1(x+1,y-a[x]-1,1);}void dfs2(int x,int y,bool f){ if (x==r+1){ if (f&&y==0) czy=1; if (f&&y>=0&&bz[y]) czy=1; return; } dfs2(x+1,y,f); if (czy) return; dfs2(x+1,y+a[x]+1,1); if (czy) return; dfs2(x+1,y-a[x]-1,1);}int main(){ //freopen("yuki.in","r",stdin);freopen("yuki.out","w",stdout); n=read();m=read();mo=read(); fo(i,0,mo-1) lf[i][0]=i*i%mo*i%mo; fo(j,1,floor(log(m)/log(2))) fo(i,0,mo-1) lf[i][j]=lf[lf[i][j-1]][j-1]; fo(i,1,n) a[i]=read(); getleaf(1,1,n); fo(i,1,m){ t=read();l=read();r=read(); if (t==1){ if (r-l+1>13){ printf("Yuno\n"); //printf("1\n"); continue; } fo(j,l,r){ query(1,1,n,j); } mid=(l+r)/2; top=0; czy=0; dfs1(l,0,0); dfs2(mid+1,0,0); fo(j,1,top) bz[b[j]]=0; if (czy) printf("Yuno\n");else printf("Yuki\n"); //if (czy) printf("1\n");else printf("0\n"); } else change(1,1,n,l,r); }}
- bzoj4722 由乃
- [bzoj4722]由乃
- [BZOJ4722]由乃 结论+线段树
- [bzoj4722]由乃 线段树 搜索 st表
- BZOJ4810 / 由乃OI2017 由乃的玉米田【莫队+Bitset】
- BZOJ4810 [Ynoi2017]由乃的玉米田
- BZOJ4811 [Ynoi2017]由乃的OJ
- BZOJ4811: [Ynoi2017]由乃的OJ 重链剖分
- 4810: [Ynoi2017]由乃的玉米田
- bzoj4810: [Ynoi2017]由乃的玉米田
- 4811: [Ynoi2017]由乃的OJ
- BZOJ4810: [Ynoi2017]由乃的玉米田
- BZOJ4865: [Ynoi2017]由乃运椰子 分块
- bzoj4810: [Ynoi2017]由乃的玉米田
- [bzoj4867] [Ynoi2017]舌尖上的由乃
- [bzoj4811] [Ynoi2017]由乃的OJ
- [Ynoi2017]舌尖上的由乃
- BZOJ4811: [Ynoi2017]由乃的OJ
- Stack源码分析
- 寒假思雨姐摸底B题
- TCP client和server 程序例子(转)
- 委托(二):委托做函数参数
- 算法竞赛入门经典 习题1-2 温度(temperature)
- [bzoj4722]由乃
- 织梦会员发表心情时会产生乱码
- 构造代码块--Java基础040
- Android Log(二) 将Log信息写到sd卡中并带时间
- HTML5-SVG练习
- ngxin请求行与请求头处理
- Weex例子——Toast
- 算法竞赛入门经典 习题1-3 连续和(sum)
- S1考试错题本及解析