zoukankan      html  css  js  c++  java
  • 8.12 NOI 模拟赛 UOJ UNR#4 T1 序列妙妙值 dp 分块优化dp 根号平衡

    LINK:序列妙妙值

    怎么人均会T1啊

    感觉上午想的时候就差一点了 因为已经注意到了 这道题可能是要折半什么的.

    后来 去刚T2了. 所以就没了.

    容易得到一个(n^2K)的做法。期望得分40.

    状态转移:(f_{i,j}=f_{k,j-1}+a_iigotimes a_k)

    其中(a_i)是异或前缀和.

    设值域为V.

    那么保存(g_i)表示 (a_k==i)是的最小(f_{k,j-1}) 那么就得到了一个(ncdot vcdot K)的做法。

    期望得分 60.

    其实可以乱搞 比如取 前255小的(a_iigotimes a_k)这样的(k)来进行更新什么的.

    上午我考虑到了另外一种想法 发现(a_i)的出现最多为V的大小.

    考虑优化上述第一个暴力,对于一个(a_i)我们肯定是要从(1-i-1)来扫获得答案.

    可以把扫到的端点及值存起来 那么对于每个本质不同的(a_i)指针最多移动n次.

    最坏复杂度(ncdot Vcdot K)

    不过很大程度上跑不满?数据不太行 所以得分80.

    code
    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<ctime>
    #include<cctype>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<ctime>
    #include<cmath>
    #include<cctype>
    #include<cstdlib>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<utility>
    #include<bitset>
    #include<set>
    #include<map>
    #define ll long long
    #define db double
    #define INF 1000000000
    #define inf 1000000000000000ll
    #define ldb long double
    #define pb push_back
    #define put_(x) printf("%d ",x);
    #define get(x) x=read()
    #define gt(x) scanf("%d",&x)
    #define gi(x) scanf("%lf",&x)
    #define put(x) printf("%d
    ",x)
    #define putl(x) printf("%lld
    ",x)
    #define rep(p,n,i) for(RE int i=p;i<=n;++i)
    #define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
    #define fep(n,p,i) for(RE int i=n;i>=p;--i)
    #define vep(p,n,i) for(RE int i=p;i<n;++i)
    #define pii pair<int,int>
    #define mk make_pair
    #define RE register
    #define P 13331ll
    #define gf(x) scanf("%lf",&x)
    #define pf(x) ((x)*(x))
    #define uint unsigned long long
    #define ui unsigned
    #define EPS 1e-5
    #define sq sqrt
    #define S second
    #define F first
    #define mod 1000000007
    #define md 998244353
    #define max(x,y) ((x)<(y)?y:x)
    #define l(i) t[i].l
    #define r(i) t[i].r
    #define mx(i) t[i].mx
    #define w(i) t[i].w
    #define zz p<<1
    #define yy p<<1|1
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
    	return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
    	RE int x=0,f=1;RE char ch=getc();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
    	return x*f;
    }
    inline ll Read()
    {
    	RE ll x=0,f=1;RE char ch=getc();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
    	return x*f;
    }
    const int MAXN=60010,maxn=4100;
    int n,K,maxx;
    int a[MAXN];
    int f[MAXN][9];
    int vis[maxn],g[maxn];
    int main()
    {
    	//freopen("1.in","r",stdin);
    	//freopen("1.out","w",stdout);
    	get(n);get(K);
    	rep(1,n,i)get(a[i]),maxx=max(maxx,a[i]),a[i]^=a[i-1],f[i][1]=a[i];
    	if(maxx<=4096)
    	{
    		maxx=255;
    		rep(2,K,j)
    		{
    			memset(vis,0x3f,sizeof(vis));
    			memset(g,0,sizeof(g));
    			rep(1,n,i)
    			{
    				while(g[a[i]]+1<i)
    				{
    					++g[a[i]];
    					vis[a[i]]=min(vis[a[i]],f[g[a[i]]][j-1]+(a[g[a[i]]]^a[i]));
    				}
    				f[i][j]=vis[a[i]];
    			}
    		}
    		rep(K,n,i)printf("%d ",f[i][K]);
    		return 0;
    	}
    	rep(1,n,i)rep(2,K,j)
    	{
    		f[i][j]=INF;
    		rep(1,i-1,k)f[i][j]=min(f[i][j],f[k][j-1]+(a[i]^a[k]));
    	}
    	rep(K,n,i)printf("%d ",f[i][K]);
    	return 0;
    }
    
    考虑正解 其实可以发现第二种方法每次更新值的时候 都是O(1)更新 O(V)查询.

    或者观察到题目中的部分分 一档(2^8)最高档(2^{16})

    其实我们折半. 也就是根号平衡.

    也就是(sqrt V)更新 (sqrt V)查询.

    那么可以设(g_{i,j})表示前8为为i 那么对于(a_i)的后8位为j的最优解.

    这样就完成了.

    code
    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<ctime>
    #include<cctype>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<ctime>
    #include<cmath>
    #include<cctype>
    #include<cstdlib>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<utility>
    #include<bitset>
    #include<set>
    #include<map>
    #define ll long long
    #define db double
    #define INF 1000000000
    #define inf 1000000000000000ll
    #define ldb long double
    #define pb push_back
    #define put_(x) printf("%d ",x);
    #define get(x) x=read()
    #define gt(x) scanf("%d",&x)
    #define gi(x) scanf("%lf",&x)
    #define put(x) printf("%d
    ",x)
    #define putl(x) printf("%lld
    ",x)
    #define rep(p,n,i) for(RE int i=p;i<=n;++i)
    #define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
    #define fep(n,p,i) for(RE int i=n;i>=p;--i)
    #define vep(p,n,i) for(RE int i=p;i<n;++i)
    #define pii pair<int,int>
    #define mk make_pair
    #define RE register
    #define P 13331ll
    #define gf(x) scanf("%lf",&x)
    #define pf(x) ((x)*(x))
    #define uint unsigned long long
    #define ui unsigned
    #define EPS 1e-5
    #define sq sqrt
    #define S second
    #define F first
    #define mod 1000000007
    #define md 998244353
    #define max(x,y) ((x)<(y)?y:x)
    #define l(i) t[i].l
    #define r(i) t[i].r
    #define mx(i) t[i].mx
    #define w(i) t[i].w
    #define zz p<<1
    #define yy p<<1|1
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
    	return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
    	RE int x=0,f=1;RE char ch=getc();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
    	return x*f;
    }
    inline ll Read()
    {
    	RE ll x=0,f=1;RE char ch=getc();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
    	return x*f;
    }
    const int MAXN=60010,maxn=256;
    int n,K,maxx;
    int a[MAXN];
    int f[MAXN][9];
    int g[maxn][maxn];
    int main()
    {
    	//freopen("1.in","r",stdin);
    	//freopen("1.out","w",stdout);
    	get(n);get(K);maxx=255;
    	rep(1,n,i)get(a[i]),a[i]^=a[i-1],f[i][1]=a[i];
    	rep(2,K,j)
    	{
    		memset(g,0x3f,sizeof(g));
    		rep(1,n,i)
    		{
    			int w1=a[i]>>8,w2=a[i]&maxx;
    			f[i][j]=INF;
    			rep(0,maxx,k)f[i][j]=min(f[i][j],g[k][w1]+(w2^k));
    			rep(0,maxx,k)g[w2][k]=min(g[w2][k],f[i][j-1]+((k^w1)<<8));
    		}
    	}
    	rep(K,n,i)printf("%d ",f[i][K]);
    	return 0;
    }
    
  • 相关阅读:
    Robot Framework接口自动化案例分享①——框架设计及GitHub源码地址
    Python开发测试工具案例分享⑨——方案总结、GitHub源码地址
    Python开发测试工具案例分享⑧——Pyinstaller工具打包exe文件
    Python开发测试工具案例分享⑦——老化测试实现代码
    Python开发测试工具案例分享⑥——登录功能实现代码
    Python开发测试工具案例分享⑤——功能测试实现代码
    Python开发测试工具案例分享④——PyQt设计功能测试界面
    Python开发测试工具案例分享③——PyQt设计老化测试界面
    数据库常见操作一
    SQL Server 2005下载安装
  • 原文地址:https://www.cnblogs.com/chdy/p/13493559.html
Copyright © 2011-2022 走看看