zoukankan      html  css  js  c++  java
  • Comet OJ Contest #3

      A:签到。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 510
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,k,a[N],f[N*N],t;
    signed main()
    {
    	n=read(),k=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=1;i<=n;i++)
    		for (int j=i+1;j<=n;j++)
    		f[++t]=a[i]+a[j];
    	sort(f+1,f+t+1);reverse(f+1,f+t+1);
    	ll ans=0;
    	for (int i=1;i<=k;i++) ans+=f[i];
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      B:找到第一个和最后一个有1的列,状压dp一下即可,即设f[i][0/1][0/1]为第i列为0/1,0/1时的最优方案要加多少个1。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 100010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,a[N][2],f[N][2][2],first,last,ans;
    signed main()
    {
    	n=read();
    	for (int i=1;i<=n;i++) a[i][0]=read();
    	for (int i=1;i<=n;i++) a[i][1]=read();
    	for (int i=1;i<=n;i++) if (a[i][0]||a[i][1]) {first=i;break;}
    	for (int i=n;i>=1;i--) if (a[i][0]||a[i][1]) {last=i;break;}
    	memset(f,42,sizeof(f));f[first-1][1][1]=0;
    	for (int i=first;i<=last;i++)
    	{
    		for (int x0=0;x0<2;x0++)
    			for (int x1=0;x1<2;x1++)
    				for (int y0=0;y0<2;y0++)
    					for (int y1=0;y1<2;y1++)
    					{
    						int tot=0;
    						if (a[i][0]==0&&x0==1) tot++;
    						if (a[i][1]==0&&x1==1) tot++;
    						if (x0==1&&y0==1||x1==1&&y1==1) f[i][x0][x1]=min(f[i][x0][x1],f[i-1][y0][y1]+tot);
    					}
    	}
    	ans=1000000000;
    	for (int i=0;i<2;i++)
    		for (int j=0;j<2;j++)
    		ans=min(ans,f[last][i][j]);
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      C:容易发现子序列中一个数的贡献是2l,而只需要考虑其是否是m的倍数,于是l超过logm后就没什么意义了。于是设f[i][j][k]为前i个数选了模m为j的k个数的方案数,转移显然。复杂度O(nmlogm),直接就可以暴力过去。事实上应该是可以做到O(nm)的,因为只需要考虑模m/2k的值。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 5010
    #define P 1000000007
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,m,a[N],f[15][N],g[N],t;
    inline void inc(int &x,int y){x+=y;if (x>=P) x-=P;}
    inline int dec(int x,int y){x-=y;if (x<0) x+=m;return x;}
    signed main()
    {
    	n=read(),m=read();int tmp=m;while (tmp%2==0) t++,tmp>>=1;t++;
    	for (int i=1;i<=n;i++) a[i]=read();
    	f[0][0]=1;
    	for (int i=1;i<=n;i++)
    	{
    		for (int j=0;j<m;j++) g[j]=f[t][j];
    		for (int j=0;j<m;j++) inc(f[t][j],g[dec(j,a[i])]);
    		for (int k=t;k;k--)
    		{
    			for (int j=0;j<m;j++)
    			{
    				inc(f[k][j],f[k-1][dec(j,a[i])]);
    			}
    		}
    	}
    	int ans=0;
    	for (int i=0;i<m;i++)
    		for (int j=1;j<=t;j++)
    		{
    			int x=i;for (int _=1;_<j;_++) x=(x<<1)%m;
    			if (x==0) inc(ans,f[j][i]);
    		}
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      D:差分序列,则区间修改变成单点修改,然后只要维护区间线性基即可,注意要强制令第一个数是否选,这样才能考虑完选偶数个数和奇数个数的情况。开始莫名其妙想成了前缀和,然后发现了一个选奇数个数的最大异或和的做法,即将每个数比最高位更高的一位设为1。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 50010
    #define P 1000000007
    #define uint int
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,m,L[N<<2],R[N<<2],tree_o[N];
    int a[N],mx;
    void  modify_o(int x,int y){while (x<=n) tree_o[x]^=y,x+=x&-x;}
    int query_o(int x){int s=0;while (x) s^=tree_o[x],x-=x&-x;return s;}
    struct base
    {
    	int b[32];
    	void ins(int v)
    	{
    		for (int i=30;~i;i--)
    		if (v&(1<<i))
    		{
    			if (b[i]==0) {b[i]=v;return;}
    			else v^=b[i];
    		}
    	}
    	int work(int v)
    	{
    		for (int i=30;~i;i--) v=max(v,v^b[i]);
    		return v;
    	}
    	void clear(){memset(b,0,sizeof(b));}
    }tree[N<<2],e;
    base merge(base x,base y)
    {
    	for (int i=30;~i;i--)
    	if (x.b[i]) y.ins(x.b[i]);
    	return y;
    }
    void build(int k,int l,int r)
    {
    	L[k]=l,R[k]=r;
    	if (l==r) {tree[k].ins(a[l]);return;}
    	int mid=l+r>>1;
    	build(k<<1,l,mid);
    	build(k<<1|1,mid+1,r);
    	tree[k]=merge(tree[k<<1],tree[k<<1|1]);
    }
    void modify(int k,int x,int p)
    {
    	if (L[k]==R[k]) {tree[k].clear();a[x]^=p;modify_o(x,p);tree[k].ins(a[x]);return;}
    	int mid=L[k]+R[k]>>1;
    	if (x<=mid) modify(k<<1,x,p);
    	else modify(k<<1|1,x,p);
    	tree[k]=merge(tree[k<<1],tree[k<<1|1]);
    }//给x xor 上p
    base query(int k,int l,int r) 
    {
    	if (l>r) return e;
    	if (L[k]==l&&R[k]==r) return tree[k];
    	int mid=L[k]+R[k]>>1;
    	if (r<=mid) return query(k<<1,l,r);
    	else if (l>mid) return query(k<<1|1,l,r);
    	else return merge(query(k<<1,l,mid),query(k<<1|1,mid+1,r));
    }//区间线性基 
    signed main()
    {
    	n=read(),m=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=n;i;i--) a[i]^=a[i-1],modify_o(i,a[i]);
    	build(1,0,n);
    	while (m--)
    	{
    		int op=read(),l=read(),r=read();
    		int v=read();
    		if (op==1)
    		{
    			modify(1,l,v);
    			if (r<n) modify(1,r+1,v);
    		}
    		else
    		{
    			int ans=max(query(1,l+1,r).work(v),query(1,l+1,r).work(v^query_o(l)));
    			printf("%d
    ",ans);
    		}
    	}
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      小裙子!

  • 相关阅读:
    rsync备份服务器搭建学习笔记
    switch case
    常见http状态码
    正则去除html字符串中的注释、标签、属性
    2018-10-10 10:00 从今日开始记录
    Qt dialog 的geometry()
    Qt禁止最大和最小化
    tableWidget删除除了头外的内容并释放
    Qt QTabBar 实现宽度调整,非QSS
    Qt 歌词有关内容
  • 原文地址:https://www.cnblogs.com/Gloid/p/10859062.html
Copyright © 2011-2022 走看看