zoukankan      html  css  js  c++  java
  • Petrozavodsk Summer-2017. Moscow IPT Contest

    A. A Place For My Head

    留坑。

    B. New Divide

    从高位到低位贪心,当这一位是$0$时,要尽量取$1$,维护高维后缀最小值进行判断即可。

    时间复杂度$O((n+a)log a)$。

    #include<cstdio>
    const int N=1000010,M=1048576;
    int n,i,j,a[N],v[M];
    inline void up(int&a,int b){a>b?(a=b):0;}
    inline int query(int p,int w){
    	int x=0;
    	for(int i=19;~i;i--)if(!(p>>i&1))if(v[x|(1<<i)]<=w)x|=1<<i;
    	return (p^x)+x;
    }
    int main(){
    	scanf("%d",&n);
    	for(i=1;i<=n;i++)scanf("%d",&a[i]),a[i]^=a[i-1];
    	for(i=0;i<M;i++)v[i]=N;
    	for(i=n;~i;i--)v[a[i]]=i;
    	for(i=M-1;~i;i--)for(j=0;j<20;j++)if(!(i>>j&1))up(v[i],v[i^(1<<j)]);
    	for(i=1;i<=n;i++)printf("%d ",query(a[i],i));
    }
    

      

    C. Lying From You

    留坑。

    D. Don’t Stay

    留坑。

    E. In The End

    留坑。

    F. From The Inside

    留坑。

    G. Numb

    留坑。

    H. One Step Closer

    留坑。

    I. Invisible

    给每个数一个随机的权值,那么若所有数权值的异或和不为$0$,则说明存在出现奇数次的数字。

    权值线段树套线段树维护异或和,在权值线段树上往下走即可。

    时间复杂度$O(nlog^2n)$。

    #include<cstdio>
    typedef unsigned int ll;
    const int N=100010,M=40000000;
    ll f[N];
    int n,m,i,op,x,y,a[N];
    int tot,l[M],r[M];ll v[M];
    int T[300000];
    void INS(int&x,int a,int b,int c,ll p){
    	if(!x){
    		x=++tot;
    	}
    	v[x]^=p;
    	if(a==b)return;
    	int mid=(a+b)>>1;
    	if(c<=mid)INS(l[x],a,mid,c,p);
    	else INS(r[x],mid+1,b,c,p);
    }
    void ins(int x,int a,int b,int c,int d,ll p){
    	INS(T[x],1,n,d,p);
    	if(a==b)return;
    	int mid=(a+b)>>1;
    	if(c<=mid)ins(x<<1,a,mid,c,d,p);
    	else ins(x<<1|1,mid+1,b,c,d,p);
    }
    ll ask(int x,int a,int b,int c,int d){
    	if(!x)return 0;
    	if(c<=a&&b<=d)return v[x];
    	int mid=(a+b)>>1;ll t=0;
    	if(c<=mid)t=ask(l[x],a,mid,c,d);
    	if(d>mid)t^=ask(r[x],mid+1,b,c,d);
    	return t;
    }
    inline int query(int c,int d){
    	int x=1,a=1,b=N;
    	while(a<b){
    		int mid=(a+b)>>1;
    		if(ask(T[x<<1],1,n,c,d)){
    			b=mid;
    			x<<=1;
    		}else{
    			a=mid+1;
    			x=x<<1|1;
    		}
    	}
    	if(!ask(T[x],1,n,c,d))return -1;
    	return a;
    }
    int main(){
    	for(i=1;i<N;i++)f[i]=f[i-1]*233+17;
    	scanf("%d",&n);
    	for(i=1;i<=n;i++)scanf("%d",&a[i]),ins(1,1,N,a[i],i,f[a[i]]);
    	while(~scanf("%d",&m)){
    		if(!m)return 0;
    		while(m--){
    			scanf("%d%d%d",&op,&x,&y);
    			if(op==1){
    				ins(1,1,N,a[x],x,f[a[x]]);
    				a[x]=y;
    				ins(1,1,N,a[x],x,f[a[x]]);
    			}else{
    				printf("%d
    ",query(x,y));
    				fflush(stdout);
    			}
    		}
    	}
    }
    

      

    J. Leave Out All The Rest

    两边的LIS都可以取到。

    #include<cstdio>
    const int N=1000010;
    int n,m,i,j,x,a[N],b[N],cnt,c[N],ans;
    inline void add(int x){
        if(x>c[cnt]){c[++cnt]=x;return;}
        int l=1,r=cnt,mid,t;
        while(l<=r)if(c[mid=(l+r)>>1]>=x)r=(t=mid)-1;else l=mid+1;
        c[t]=x;
    }
    int main(){
        scanf("%d",&n);
        for(i=1;i<=n;i++)scanf("%d",&x),add(x);
        ans=cnt;
        cnt=0;
        scanf("%d",&m);
        for(i=1;i<=m;i++)scanf("%d",&x),add(x);
        printf("%d",cnt+ans);
    }
    

      

    K. Faint

    找规律发现每个数的贡献和组合数有关。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<string>
    #include<ctype.h>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<algorithm>
    #include<time.h>
    using namespace std;
    void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
    #define MS(x, y) memset(x, y, sizeof(x))
    #define ls o<<1
    #define rs o<<1|1
    typedef long long LL;
    typedef unsigned long long UL;
    typedef unsigned int UI;
    template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
    template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
    const int N = 1e5 + 10, M = 1e5 + 10, Z = 1e9 + 7, inf = 0x3f3f3f3f;
    template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
    const int LIM=3000000;
    int casenum, casei;
    LL n, K, m;
    LL fac[LIM],inv[LIM];
    int c(int n, int m)
    {
    	if(n<m)return 0;
    	return fac[n]*inv[m]%Z*inv[n-m]%Z;
    	//LL rtn = 1;
    	//for(int i = m + 1; i <= n; ++i)rtn *= i;
    	//for(int i = 1; i <= n - m; ++i)rtn /= i;
    	//return rtn;
    }
    int main()
    {
    	int i;
    	for(fac[0]=i=1;i<LIM;i++)fac[i]=1LL*fac[i-1]*i%Z;
    	for(inv[0]=inv[1]=1,i=2;i<LIM;i++)inv[i]=1LL*(Z-inv[Z%i])*(Z/i)%Z;
    	for(i=2;i<LIM;i++)inv[i]=1LL*inv[i-1]*inv[i]%Z;
        while(~scanf("%lld%lld%lld", &n, &K, &m))
    	{
    		if(m == 1)
    		{
    			printf("%d
    ", n - K);
    			continue;
    		}
    		int sum = 0;
    		int val = 0;
    		for(int i = 1; i <= n - K; ++i)
    		{
    			int num = c(i - 1 + m - 2, i - 1);
    			sum += num;
    			sum%=Z;
    			val += 1LL*num * i%Z;
    			val%=Z;
    		}
    		
    		int top = 1LL*sum * (n - K + 1)%Z;
    		int bot = val;
    		//printf("%d
    ", top); printf("%d
    ", bot);
    		LL ans = 1LL*(top - bot) * 2 - (n - K);
    		printf("%lld
    ", (ans%Z+Z)%Z);
    	}
    	return 0;
    }
    /*
    【trick&&吐槽】
    
    
    【题意】
    
    
    【分析】
    
    
    【时间复杂度&&优化】
    
    
    */
    

      

  • 相关阅读:
    0309. Best Time to Buy and Sell Stock with Cooldown (M)
    0621. Task Scheduler (M)
    0106. Construct Binary Tree from Inorder and Postorder Traversal (M)
    0258. Add Digits (E)
    0154. Find Minimum in Rotated Sorted Array II (H)
    0797. All Paths From Source to Target (M)
    0260. Single Number III (M)
    0072. Edit Distance (H)
    0103. Binary Tree Zigzag Level Order Traversal (M)
    0312. Burst Balloons (H)
  • 原文地址:https://www.cnblogs.com/clrs97/p/7740777.html
Copyright © 2011-2022 走看看