zoukankan      html  css  js  c++  java
  • jsoi2015R2D2和R3D1测试总结

    传送门:然而并没有...

    这两天测试状态比较奇怪,前面1.5h-2h完全不知所措,一脸茫然,感觉自己吃枣药丸

    后面才发现有很多题可捉的,并没有想象的那么难,但是时间已经不充裕了...


    R2D2

    T1:不知所措数学题

    一开始总想着有什么DP可以拿一些部分分

    然而连30分DP都不会....

    咦,好像有大样例

    那就找一发规律

    妈呀真是2^(nk)

    快速幂完事....


    考完冷静了一下发现还是比较容易证的

    首先n位每位相互独立,所以可以只考虑一位

    设f[k]表示k*k的三角形的方案数

    考虑f[k+1]怎么递推

    如果最左下角的数是0,那么最后一行已经确定了,都会是0

    而且不会对上面的k*k的三角形有影响,所以方案数是f[k]

    如果是1,同理,最左边一行已经确定了,都必须是1

    而且也不会对右边的k*k的三角形有影响,所以方案数是f[k]

    所以f[k+1]=2*f[k]

    所以一位的答案就是2^k

    n位乘起来就好了,答案就是2^(nk)


    T2:数据结构题?

    一看到这题我就觉得是数据结构题,然而想来想去并不知道怎么维护....于是弃疗了

    后来我才发现一个显然的性质

    就是最大和最小一定取在端点,不然不是最优

    然后我们就可以分数规划了

    情况有点多

    假设i是右端点,j是左端点

    假设a[i]为max,a[j]为min

    那么(a[i]-a[j])/(i-j+K)=ans

    变形得(a[i]-i*ans)-(a[j]-j*ans)=k*ans

    所以我们二分一下ans,有满足左边大于右边的,ans就可以更大

    左边最大值可以用单调队列做

    记A[i]=a[i]-ans*i

    如果后面加进来的A[i]比队尾要小,队尾就没有意义了,可以删去

    对于区间长度是[L,R]的限制,初始时保持距离为L,加入队列时从队头删去距离超过R-1的点即可

    反过来类似,注意一些细节


    另外就是区间长为L时

    类似地,(a[i]-a[j])/(L-1+K)=ans

    变形得:a[i]-a[j]=ans*(L-1+K)

    也是二分,单调队列维护即可

    复杂度O(nlogmaxans)


    T3:字符串神题?

    突然发现字符串长<=10.....

    拿个可持久化trie维护一下就好了

    儿子节点从父亲节点继承trie,再把边上的字符串插入进去即可

    每次用ans[x]+ans[y]-2*ans[lca]即可


    R3D1

    T1:一开始想到了一个玄学做法,好像很复杂的样子...然后就安心打暴力去了

    后来证了一下发现是对了,加个bitset好像可以卡过


    我们对于每个点求出它能到哪些点,记为g[i][maxn],这个可以压位做到m*n/32

    然后对于每个点v,处理哪些连向它的边可删

    如果一个它的前驱x能够到它的另一个前驱y

    那么显然x连向它的边可以删去了

    然后证明没有其他可删的边

    假设有一个边可删,且不满足上面的条件

    那么说明x到v有其他路径

    那么这条路经一定要经过v的另一个前驱z,那么x可以到z,不符假设

    所以不存在这样的边

    具体实现就对每个点求一个bitset,表示是否是x的前驱

    在把它和每个前驱的g[i]and一下,如果有1,就说明可以从其他点过来,然后就可以删掉这条边

    然后发现有点卡常,怕70分都没了,于是只开到1000,70保平安...

    然后发现标程压64位.....


    T2:神奇的插头DP


    妈呀200*200....

    一定有特殊的DP方法

    D了半天不知所措....


    突然发现这是很简单的网络流,每栋房子是一个点,源向它连卖给A的权值,它向汇连卖给B的的权值,相邻的点连建围墙的权值,求出最小割,拿总收益减去就是了...


    然后就是15分钟写网络流系列...

    然后就爆零被教做人了...


    T3:这个真是字符串神题,看了标程好像是后缀数组,暴力还挂了,不知所措...


    得分情况:100+0+100+70+0+0

    有些题目就是要敢于去想,要相信能写出来

    但是有时写暴力求稳也是很重要的...



    R2D1

    T1:

    <span style="font-size:14px;">#include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    typedef long long ll;
    const ll mod=(ll)1e9+7;
    using namespace std;
    int n,k;
    
    ll qpow(int a,ll b){
    	ll res=1,j=a;
    	while (b){
    		if (b&1) res=res*j%mod;
    		j=j*j%mod,b>>=1;
    	}
    	return res;
    }
    
    int main(){
    	scanf("%d%d",&n,&k);
    	printf("%lld
    ",qpow(2,1ll*n*k));
    	return 0;
    }</span>

    T2:
    <span style="font-size:14px;">#include<cstdio>
    #include<cstring>
    #include<cassert>
    #include<iostream>
    #include<algorithm>
    const double eps=1e-6;
    const int maxn=100010;
    using namespace std;
    int cas,a[maxn],n,K,L,R;
    struct Tque{
    	int pos[maxn],head,tail;double val[maxn];
    	void clear(){head=1,tail=0;}
    	void pushmin(int p,double v){
    		//maximize a[i]-miu*i-a[j]+miu*j
    		//if A[j]<=A[q[tail]] 
    		//because j>q[tail]
    		//j is better than q[tail]
    		while (head<=tail&&v<=val[tail]) tail--;
    		val[++tail]=v,pos[tail]=p;
    	}
    	void pushmax(int p,double v){
    		while (head<=tail&&v>=val[tail]) tail--;
    		val[++tail]=v,pos[tail]=p;
    	}
    	void pop1(int p){while (head<=tail&&p-pos[head]+1>R) ++head;assert(p-pos[head]+1<=R);}
    	void pop2(int p){while (head<=tail&&pos[head]<p-L+1) ++head;assert(pos[head]>=p-L+1);}
    	double top(){return val[head];}
    }q;
    
    bool check(double miu){
    	q.clear();
    	for (int i=L;i<=n;i++){
    		int j=i-L+1;
    		q.pushmin(j,a[j]-j*miu),q.pop1(i);
    		if (a[i]-miu*i-q.top()+eps>=K*miu) return 1;
    	}
    	q.clear();
    	for (int i=L;i<=n;i++){
    		int j=i-L+1;
    		q.pushmax(j,a[j]+j*miu),q.pop1(i);
    		if (q.top()-a[i]-miu*i+eps>=K*miu) return 1;
    	}
    	q.clear();
    	for (int i=1;i<=n;i++){
    		q.pushmin(i,a[i]),q.pop2(i);
    		if (a[i]-q.top()+eps>=(L-1+K)*miu) return 1;
    	}
    	q.clear();
    	for (int i=1;i<=n;i++){
    		q.pushmax(i,a[i]),q.pop2(i);
    		if (q.top()-a[i]+eps>=(L-1+K)*miu) return 1;
    	}
    	return 0;
    }
    
    int main(){
    	//freopen("gift.in","r",stdin);freopen("gift.out","w",stdout);
    	scanf("%d",&cas);
    	while (cas--){
    		scanf("%d%d%d%d",&n,&K,&L,&R);
    		for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    		double l=0.0,r=1000.0,mid=500.0;
    		while (r-l>eps){
    			if (check(mid)) l=mid;
    			else r=mid;
    			mid=(l+r)/2;
    		}
    		printf("%.4lf
    ",l);
    	}
    	return 0;
    }
    /*
    1
    5 1 2 4
    1 2 3 4 5
    */
    </span>

    T3:

    <span style="font-size:14px;">#include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    const int maxn=100010,maxm=200010,maxt=1200010;
    using namespace std;
    int n,Q,pre[maxm],now[maxn],son[maxm],val[maxm][15],tot,pp[15],fa[maxn][22],dep[maxn];char tmp[15];
    
    struct Trie{
    	int root[maxn],ch[maxt][28],tot,cnt[maxt];
    	void insert(int now,int pre,int s[]){
    		int len=0;
    		while (s[len+1]) len++;
    		//for (int i=1;i<=len;i++) printf("%d ",s[i]);puts("s[i]");
    		for (int i=1;i<=len;i++){
    			for (int j=1;j<=26;j++){
    				if (j==s[i]) ch[now][j]=++tot,cnt[tot]=cnt[ch[pre][j]]+1;
    				else ch[now][j]=ch[pre][j];
    			}
    			now=ch[now][s[i]],pre=ch[pre][s[i]];
    		}
    		for (int j=1;j<=26;j++) ch[now][j]=ch[pre][j];
    	}
    	int query(int now,int s[]){
    		for (int i=1;s[i];i++) now=ch[now][s[i]];//,printf("now=%d s[i]=%d cnt=%d
    ",now,s[i],cnt[now])
    		//puts("
    ");
    		return cnt[now];
    	}
    }T;
    
    void add(int a,int b){
    	pre[++tot]=now[a],now[a]=tot,son[tot]=b;
    	for (int i=1;pp[i];i++) val[tot][i]=pp[i];
    }
    
    void dfs(int x){
    	for (int i=1;i<=19;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
    	for (int y=now[x];y;y=pre[y]) if (son[y]!=fa[x][0]){
    		T.root[son[y]]=++T.tot,T.insert(T.root[son[y]],T.root[x],val[y]);
    		dep[son[y]]=dep[x]+1,fa[son[y]][0]=x,dfs(son[y]);
    	}
    }
    
    int lca(int a,int b){
    	if (dep[a]<dep[b]) swap(a,b);
    	for (int h=dep[a]-dep[b],i=18;h;i--) if (h&(1<<i)) h-=(1<<i),a=fa[a][i];
    	if (a==b) return a;
    	for (int i=18;i>=0;i--)
    		if (fa[a][i]!=fa[b][i]) a=fa[a][i],b=fa[b][i];
    	return fa[a][0];
    }
    
    void change(){
    	int len=strlen(tmp+1);
    	memset(pp,0,sizeof(pp));
    	for (int i=1;i<=len;i++) pp[i]=tmp[i]-'a'+1;
    }
    
    int main(){
    	freopen("strings.in","r",stdin);freopen("strings.out","w",stdout);
    	scanf("%d",&n);
    	for (int i=1,x,y;i<n;i++){
    		scanf("%d%d%s",&x,&y,tmp+1);
    		change(),add(x,y),add(y,x);
    	}
    	T.root[1]=++T.tot,dfs(1);
    	scanf("%d",&Q);
    	for (int i=1,x,y;i<=Q;i++){
    		scanf("%d%d%s",&x,&y,tmp+1);
    		int u=lca(x,y);change();
    		//printf("x=%d y=%d lca=%d
    ",x,y,u);
    		printf("%d
    ",T.query(T.root[x],pp)+T.query(T.root[y],pp)-2*T.query(T.root[u],pp));
    		/*printf("x=%d
    ",T.query(T.root[x],pp));
    		printf("y=%d
    ",T.query(T.root[y],pp));
    		printf("lca=%d
    ",T.query(T.root[u],pp));*/
    	}
    	return 0;
    }</span>

    R3D1

    T1:这个程序只能过70分,但是是标算,还要特殊的卡常数技巧(标程是压64位,可能在64位机上要快一些就过了)

    #include<cstdio>
    #include<bitset>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    const int maxn1=18,maxn=30010,maxm=100010;
    using namespace std;
    struct Edge{int x,y;}E[maxm];
    bitset<maxn> map[maxn];
    int n,m,ans,pw[maxn1],ord[maxn];bool g[maxn1][maxn1],con[maxn1][maxn1],tmp[maxn1][maxn1],bo[maxn1];
    
    struct Twork1{
    	void dfs(int x){
    		bo[x]=1;
    		for (int i=1;i<=n;i++) if (g[x][i]&&!bo[i]) dfs(i);
    	}
    	bool check(int s){
    		memset(g,0,sizeof(g)),memset(tmp,0,sizeof(tmp));
    		for (int i=0;i<m;i++) if (pw[i]&s) g[E[i].x][E[i].y]=1;
    		for (int i=1;i<=n;i++){
    			memset(bo,0,sizeof(bo)),dfs(i);
    			for (int j=1;j<=n;j++) if (bo[j]) tmp[i][j]=1;
    		}
    		for (int i=1;i<=n;i++)
    			for (int j=1;j<=n;j++) if (tmp[i][j]!=con[i][j]) return 0;
    		return 1;
    	}
    	void work(){
    		for (int i=0;i<m;i++) scanf("%d%d",&E[i].x,&E[i].y),g[E[i].x][E[i].y]=1;
    		for (int i=1;i<=n;i++){
    			memset(bo,0,sizeof(bo)),dfs(i);
    			for (int j=1;j<=n;j++) if (bo[j]) con[i][j]=1;
    		}
    		for (int s=0;s<pw[m];s++){
    			int cnt=0;
    			for (int i=0;i<m;i++) if (s&pw[i]) cnt++;
    			cnt=m-cnt;
    			//printf("%d %d
    ",s,cnt);
    			if (check(s)) ans=max(cnt,ans);
    		}
    		printf("%d
    ",ans);
    	}
    }T1;
    
    struct Twork2{
    	int pre[maxm],now[maxn],son[maxm],tot,in[maxn],q[maxn],head,tail;
    	void add(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b,in[b]++;}
    	void top1(){
    		head=0,tail=0;
    		for (int i=1;i<=n;i++) map[i][i]=1;
    		for (int i=1;i<=n;i++) if (!in[i]) q[++tail]=i;
    		while (head!=tail){
    			int x=q[++head];
    			for (int y=now[x];y;y=pre[y]){
    				if (!(--in[son[y]])) q[++tail]=son[y];
    				map[son[y]]|=map[x];
    			}
    		}
    		for (int i=1;i<=n;i++) map[i][i]=0;
    	}
    	void work(){
    		for (int i=1,x,y;i<=m;i++) scanf("%d%d",&x,&y),add(y,x);
    		top1();
    		bitset<maxn> tmp;
    		int ans=0;
    		for (int x=1;x<=n;x++){
    			tmp.reset();
    			for (int y=now[x];y;y=pre[y])
    				tmp[son[y]]=1;
    			for (int y=now[x];y;y=pre[y])
    				if ((tmp&map[son[y]]).any()) ans++;
    		}
    		printf("%d
    ",ans);
    	}		
    }T2;
    
    int main(){
    	freopen("graph.in","r",stdin);freopen("graph.out","w",stdout);
    	pw[0]=1;for (int i=1;i<=16;i++) pw[i]=pw[i-1]<<1;
    	scanf("%d%d",&n,&m);
    	if (n<=15&&m<=15) T1.work();
    	else T2.work();
    	return 0;
    }
    /*
    5 6
    1 2
    2 3
    3 5
    4 5
    1 5
    1 3
    
    7 8
    1 2
    2 5
    5 7
    1 3
    6 7
    1 4
    4 7
    3 5
    
    */

    T2:
    #include<cstdio>
    #include<cassert>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define aabs(a) (a>0?a:-(a))
    const int maxn=500010,maxm=1000010,inf=(int)1e9;
    using namespace std;
    int n,m,ans,pre[maxm],now[maxn],son[maxm],val[maxm],tot,dis[maxn],head,tail,q[maxm+10];
    int id(int x,int y){return (x-1)*m+y;}
    
    struct Flow{
    	int S,T;
    	void add(int a,int b,int c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
    	void ins(int a,int b,int c){add(a,b,c),add(b,a,0);assert(tot<maxn);}
    	void clear(){memset(now,0,sizeof(now)),tot=1,S=0,T=maxn-1;}
    	bool bfs(){
    		memset(dis,-1,sizeof(dis));
    		q[tail=1]=S,dis[S]=head=0;
    		while (head!=tail){
    			if (++head>maxn) head=1;
    			int x=q[head];
    			for (int y=now[x];y;y=pre[y])
    				if (val[y]&&dis[son[y]]==-1){
    					if (++tail>maxn) tail=1;
    					dis[son[y]]=dis[x]+1,q[tail]=son[y];
    				}
    		}
    		return dis[T]>0;
    	}
    	int find(int x,int low){
    		if (x==T) return low;
    		int y,res=0;
    		for (y=now[x];y;y=pre[y]){
    			if (dis[son[y]]!=dis[x]+1||!val[y]) continue;
    			int tmp=find(son[y],min(low,val[y]));
    			res+=tmp,low-=tmp,val[y]-=tmp,val[y^1]+=tmp;
    			if (!low) break;
    		}
    		if (!y) dis[x]=-1;
    		return res;
    	}
    	void work(){
    		int res=0;
    		while (bfs()) res+=find(S,inf);
    		printf("%d
    ",ans-res);
    	}
    }F;
    
    void init(){
    	scanf("%d%d",&n,&m),F.clear();
    	for (int i=1;i<=n;i++)
    		for (int j=1,v;j<=m;j++){
    			scanf("%d",&v),ans+=aabs(v);
    			if (v>=0) F.ins(F.S,id(i,j),v);
    			else F.ins(id(i,j),F.T,-v);
    		}
    	for (int i=1;i<n;i++)
    		for (int j=1,v;j<=m;j++)
    			scanf("%d",&v),F.ins(id(i,j),id(i+1,j),v),F.ins(id(i+1,j),id(i,j),v);
    	for (int i=1;i<=n;i++)
    		for (int j=1,v;j<m;j++)
    			scanf("%d",&v),F.ins(id(i,j),id(i,j+1),v),F.ins(id(i,j+1),id(i,j),v);
    }
    
    int main(){
    	init(),F.work();
    	return 0;
    }
    /*
    5 5
    -3 7 0 0 0
    8 0 7 -10 0
    0 7 0 1 0
    0 0 0 0 0
    -8 0 0 2 10
    4 50 50 1 50
    50 50 1 9 50
    50 50 1 1 50
    2 50 50 50 50
    2 50 50 50
    50 50 1 1
    50 1 8 1
    50 50 50 50
    1 50 50 50
    */

    T3:不知所措....



  • 相关阅读:
    es date_histogram强制补零
    macos下默认的调试工具是lldb
    test
    mybaity 代码自动生成器
    初始化的问题
    SQLServer常用语句
    PowerShell Install-Module 离线安装 .nupkg包
    .NET Core语句记录
    system design(how to design tweet)
    软件-开源
  • 原文地址:https://www.cnblogs.com/thythy/p/5493643.html
Copyright © 2011-2022 走看看