• bzoj 4722 由乃


    bzoj

    先考虑一种简单的情况,即这个区间是否有相同的数,因为值域大小为1000,那么当区间长度(>1000)时,根据鸽巢原理,一定会有两个相同的数,这时候可以直接输出Yuno

    进一步的,对于长度为(len)的区间,子集的值域为([0,v*len]),子集个数为(2^{len}),那么可以得到如果满足(2^{len}>v*len+1)的区间,一定有两个一样权值的子集(有交就把交去掉),可以解得这个界为(lenge 14).那么对于(le 13)的部分,就暴力枚举每个数在哪个集合中,或者是不在集合中,复杂度(O(3^{len})),其实可以(meet in the middle),先搜前一半,得到所有选取情况下(A)集合权值(-B)集合权值的值,然后搜另一个集合,直接查是否存在对应(A)集合权值(-B)集合权值的相反数,以及是否有那个值为0的方案,复杂度(O(3^{frac{len}{2}}))

    至于修改操作,那么每次询问这个值的时候给他修改总修改次数-以及修改次数 次,因为这个修改可以看成在有向图上走(x)步,所以可以预处理走一些步数的情况,修改时直接大力跳即可

    #include<bits/stdc++.h>
    #define LL long long
    #define uLL unsigned long long
    #define db double
    
    using namespace std;
    const int N=1e5+10,M=1000+10;
    int rd()
    {
    	int x=0,w=1;char ch=0;
    	while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    	return x*w;
    }
    int n,q,v,to[M][M],cn[N],a[N],bt[N];
    void add(int x,int y){while(x<=n) bt[x]+=y,x+=x&(-x);}
    int gsm(int x){int an=0;while(x) an+=bt[x],x-=x&(-x);return an;}
    int bk[N],st[M<<2],tp,s2[M<<2],t2;
    void wk(int x)
    {
    	int dt=gsm(x)-cn[x];
    	cn[x]+=dt;
    	while(dt>v) a[x]=to[a[x]][v],dt-=v;
    	a[x]=to[a[x]][dt];
    }
    
    int main()
    {
    	n=rd(),q=rd(),v=rd();
    	for(int i=1;i<=n;++i) a[i]=rd();
    	for(int i=0;i<v;++i) to[i][0]=i,to[i][1]=1ll*i*i*i%v;
    	for(int j=2;j<=v;++j)
    		for(int i=0;i<v;++i)
    			to[i][j]=to[to[i][j-1]][1];
    	while(q--)
    	{
    		int op=rd(),l=rd(),r=rd();
    		if(op==2) add(l,1),add(r+1,-1);
    		else
    		{
    			if(r-l+1>=14) puts("Yuno");
    			else
    			{
    				int md=(r-l+1)/2;
    				bool ok=0;
    				st[tp=1]=50000;
    				for(int i=l;i<=l+md-1;++i)
    				{
    					wk(i);
    					int latp=tp;
    					for(int j=1;j<=latp;++j)
    					{
    						st[++tp]=st[j]+a[i]+1;
    						ok|=st[tp]==50000,++bk[st[tp]];
    						st[++tp]=st[j]-(a[i]+1);
    						ok|=st[tp]==50000,++bk[st[tp]];
    					}
    				}
    				s2[t2=1]=50000;
    				for(int i=l+md;!ok&&i<=r;++i)
    				{
    					wk(i);
    					int latp=t2;
    					for(int j=1;j<=latp;++j)
    					{
    						s2[++t2]=s2[j]+a[i]+1;
    						ok|=s2[t2]==50000||bk[100000-s2[t2]];
    						s2[++t2]=s2[j]-(a[i]+1);
    						ok|=s2[t2]==50000||bk[100000-s2[t2]];
    					}
    				}
    				puts(ok?"Yuno":"Yuki");
    				while(tp>1) bk[st[tp]]=0,--tp;
    			}
    		}
    	}
        return 0;
    }
    
  • 相关阅读:
    STM32 Cube之旅-尝试新的开发方式
    FOC 电流采样为什么不准?你忽略了这个细节
    STM32 外部中断详解(原理+配置代码)
    STM32 TIM高级定时器死区时间的计算
    【STM32系列汇总】小白博主的STM32实战快速进阶之路(持续更新)
    FOC 算法基础之欧拉公式
    一阶RC高通滤波器详解(仿真+matlab+C语言实现)
    一阶RC低通滤波器详解(仿真+matlab+C语言实现)
    matlab 调用C程序进行simulink仿真
    matlab 提示 Error using mex No supported compiler or SDK was found 错误的解决办法
  • 原文地址:https://www.cnblogs.com/smyjr/p/11600809.html
Copyright © 2020-2023  润新知