zoukankan      html  css  js  c++  java
  • 【洛谷5527】[Ynoi2012] NOIP2016人生巅峰(抽屉原理+暴力)

    点此看题面

    大致题意: 给定一个序列({a_i}),支持两种操作:询问是否能在一个区间中选出两个无交集的非空下标集合,使得(sum(a_i+1))的值相等;将一个区间内的(a_i)全部修改为(a_i^3 mod v)

    抽屉原理

    首先,虽然题目要求下标集合无交集,但是如果两个值相等的集合有交集,我们完全可以同时消去交集部分。因此这个限制可以直接忽略。

    假设一个长度为(l)的区间可能无解,由于每个数可以选或不选,共有(2^l-1)种选数方案,而无解也就要求每种选数方案得到的数两两不同,即:

    [2^l-1>1000 imes l ]

    得出(lle 13)

    也就是说,我们只需考虑区间长度小于等于(13)的情况即可。

    那么直接暴搜似乎就可以?(常数小跑不满

    不过如果你一定要保证复杂度,可以去写(Meet in Middle),反正我直接暴力水过了。。。

    修改

    考虑如何处理区间立方的操作。

    显然容易维护出一个数被立方操作的次数,每次询问前用扩展欧拉定理即可求出每个数的值。

    写到这里突然发现我原先的做法写复杂了,我原本是直接维护一个数的指数,这样还要判断指数是否超过过(phi(v)),非常麻烦。。。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define V 1000
    using namespace std;
    int n,v,p,ti,sz,a[N+5],s[N+5],bl[N+5],pw[V+5][2*V+5],vis[N*V+5];
    int f[N+5],ff[N+5],g[N+5],gg[N+5];
    class FastIO
    {
    	private:
    		#define FS 100000
    		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
    		#define D isdigit(c=tc())
    		char c,*A,*B,FI[FS];
    	public:
    		I FastIO() {A=B=FI;}
    		Tp I void read(Ty& x) {x=0;W(!D);W(x=(x<<3)+(x<<1)+(c&15),D);}
    }F;
    I int gcd(CI x,CI y) {return y?gcd(y,x%y):x;}
    I void GetPhi(RI x)//求phi
    {
    	RI i;for(p=1,i=2;i*i<=x;++i) if(!(x%i)) {p*=i-1,x/=i;W(!(x%i)) p*=i,x/=i;}x^1&&(p*=x-1);
    }
    I bool dfs(CI x,CI y,CI t=0,CI f=0)//暴搜
    {
    	if(f) {if(vis[t]==ti) return 1;vis[t]=ti;}if(x>y) return 0;
    	if(dfs(x+1,y,t,0)) return 1;return dfs(x+1,y,t+s[x],1);
    }
    int main()
    {
    	RI Qt,i,j;F.read(n),F.read(Qt),F.read(v),GetPhi(v);
    	for(i=0;i^v;++i) for(pw[i][0]=j=1;j<=2*p;++j) pw[i][j]=pw[i][j-1]*i%v;//预处理幂
    	for(sz=sqrt(n),i=1;i<=n;++i) F.read(a[i]),f[i]=g[bl[i]=(i-1)/sz+1]=1;
    	RI op,x,y;W(Qt--) switch(F.read(op),F.read(x),F.read(y),op)
    	{
    		case 1:if(y-x+1>=14) {puts("Yuno");break;}for(++ti,i=x;i<=y;++i)//长度过长必然有解
    				s[i]=pw[a[i]][f[i]*g[bl[i]]%p+(gcd(a[i],v)^1&&(ff[i]||gg[bl[i]]||f[i]*g[bl[i]]>=p)?p:0)]+1;//扩展欧拉定理求值
    			puts(dfs(x,y)?"Yuno":"Yuki");break;//暴搜验证
    		case 2:if(bl[x]==bl[y]) {for(i=x;i<=y;++i) (f[i]*=3)>=p&&(f[i]%=p,ff[i]=1);break;}//Ynoi怎么能不写分块。。。
    			for(i=bl[x]*sz;i>=x;--i) (f[i]*=3)>=p&&(f[i]%=p,ff[i]=1);
    			for(i=(bl[y]-1)*sz+1;i<=y;++i) (f[i]*=3)>=p&&(f[i]%=p,ff[i]=1);
    			for(i=bl[x]+1;i^bl[y];++i) (g[i]*=3)>=p&&(g[i]%=p,gg[i]=1);break;
    	}return 0;
    }
    
  • 相关阅读:
    Client does not support authentication protocol requested by server 解决Navicat连接不上MySql服务器报错
    chmod使用简记
    心跳ajax请求pending状态(被挂起),stalled时间过长的问题。涉及tcp连接异常
    java判断两个对象是否相同个方法源码分析
    删除properties换成yml文件时
    banner图案
    springboot中banner里面可以写的一些信息
    lombok注解简介
    常见的模版引擎
    关于内网部署序列化数据添加更新传输问题
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu5527.html
Copyright © 2011-2022 走看看