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&&吐槽】
    
    
    【题意】
    
    
    【分析】
    
    
    【时间复杂度&&优化】
    
    
    */
    

      

  • 相关阅读:
    CSU1661: Query Mutiple
    U磁盘检测和大量收集量产工具
    DBMS_RLS包实现数据库表中的行级安全控制
    vim note(4)
    android 时间对话框 TimePickerDialog简介
    手动露天广场和立方体
    将JDBC ResultSet结果集变成List
    PS CS5如何在一张图片里插入另一张图片?
    图文教您轻松学会用PS设计制作名片
    常用颜色的RGB值
  • 原文地址:https://www.cnblogs.com/clrs97/p/7740777.html
Copyright © 2011-2022 走看看