• Luogu P5527 [Ynoi2012]NOIP2016人生巅峰


    智推给我的ynoi,自习课想了一下就会做了,真是小清新(虽然猜了一个错结论但还是过了)

    首先我们发现如果我们选的是非空集合那么限制(1)就是假的,因此我们可以把两个集合的交全部去掉然后剩下的部分依然是合法的

    所以我们现在就是要在区间里找两个集合使得它们和相等,显然我们可以爆搜

    但是区间长度太长的时候就GG了,我们考虑当数很多的时候有可能的数和骑士很多,根据抽屉原理我们容易得到一个上界(13)

    然而我做题的时候错误地计算了上界为(9)竟然还过了的说……

    考虑我们现在只需要考虑(r-l+1le 13)的情况,那么直接经典折半搜索即可(然而我太懒了并没有写)

    然后就是维护每个数的值了,容易发现我们可以直接树状数组维护每个数被立方的次数,然后利用扩展欧拉定理直接求出区间每个数的值即可

    注意是扩展的因此要判断(3^c)(varphi(v))的大小,这个直接取个对数即可

    #include<cstdio>
    #include<cmath>
    #define RI register int
    #define CI const int&
    using namespace std;
    const int N=100005,M=1005;
    int n,m,mod,a[N],b[N],opt,l,r,phi; bool flag,ct[M*10];
    inline int gcd(CI x,CI y)
    {
    	return y?gcd(y,x%y):x;
    }
    inline int quick_pow(int x,int p,int mod,int mul=1)
    {
    	for (;p;p>>=1,(x*=x)%=mod) if (p&1) (mul*=x)%=mod; return mul;
    }
    inline int M_pow(int x,int p,int mul=1)
    {
    	for (;p;p>>=1,x*=x) if (p&1) mul*=x; return mul;
    }
    class Tree_Array
    {
    	private:
    		#define lowbit(x) (x&-x)
    		int bit[N];
    	public:
    		inline void add(RI x,CI y)
    		{
    			for (;x<=n;x+=lowbit(x)) bit[x]+=y;
    		}
    		inline int get(RI x,int ret=0)
    		{
    			for (;x;x-=lowbit(x)) ret+=bit[x]; return ret;
    		}
    		#undef lowbit
    }BIT;
    inline void DFS(CI nw,CI tar,int sum=0)
    {
    	if (nw>tar) { if (ct[sum]) flag=1; ct[sum]=1; return; }
    	DFS(nw+1,tar,sum+b[nw]); DFS(nw+1,tar,sum);
    }
    inline void recover(CI nw,CI tar,int sum=0)
    {
    	if (nw>tar) return (void)(ct[sum]=0);
    	recover(nw+1,tar,sum+b[nw]); recover(nw+1,tar,sum);
    }
    int main()
    {
    	RI i,j; for (scanf("%d%d%d",&n,&m,&mod),i=1;i<=mod;++i)
    	if (gcd(i,mod)==1) ++phi; for (i=1;i<=n;++i) scanf("%d",&a[i]);
    	for (i=1;i<=m;++i)
    	{
    		scanf("%d%d%d",&opt,&l,&r); if (opt==2) BIT.add(l,1),BIT.add(r+1,-1); else
    		{
    			if (r-l+1>=10) { puts("Yuno"); continue; } for (j=l;j<=r;++j)
    			{
    				int c=BIT.get(j); if (log(3)*c<log(phi)) b[j]=quick_pow(a[j],M_pow(3,c),mod)+1;
    				else b[j]=quick_pow(a[j],quick_pow(3,c,phi)+phi,mod)+1; //printf("%d%c",b[j]," 
    "[j==r]);
    			}
    			flag=0; DFS(l,r); recover(l,r); puts(flag?"Yuno":"Yuki");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    HTML <input> 标签
    HTML5 <input> type 属性
    静态页面与动态页面
    string::size_type 页73 size_t 页90
    template method(模板方法)
    C++中创建对象的时候加括号和不加括号的区别(转)
    _declspec(dllexport)和.def(转)
    智能指针
    C++中的delete加深认识
    工厂方法(整理自李建忠<C++设计模式>视频)
  • 原文地址:https://www.cnblogs.com/cjjsb/p/13080793.html
Copyright © 2020-2023  润新知