zoukankan      html  css  js  c++  java
  • CSPJ简易题解

    T1

    显然的二进制拆分。

    由于闲的没事干所以写了个栈(

    采用树状数组那样的 lowbit 写法求出每一个 (1)

    代码:

    #if 0
    长春这天下大雨,武昌这天下大雨。
    连续两天下大雨,持续两天下大雨。
    东京前天下大雨,龙华前天下大雨。
    显然今天下大雨,勿忘今天下大雨。
    双人飞天下大雨,泪雨滂沱下大雨。
    我也想他下大雨,直接让他下大雨。
    德州后天下大雨,虽然昨天下大雨。
    六月份天下大雨,后五月天下大雨。 
    #endif
    #include<bits/stdc++.h>
    using namespace std;
    int read(){
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar()))x=x*10+(ch^'0');
    	return x;
    }
    int main(){
    	freopen("power.in","r",stdin);
    	freopen("power.out","w",stdout);
    	int n=read();
    	if(n&1)puts("-1");
    	else{
    		stack<int>tmp;
    		while(n)tmp.push(n&-n),n&=n-1;
    		while(!tmp.empty())printf("%d ",tmp.top()),tmp.pop();
    	}fflush(stdout);
    	return 0;
    }
    

    T2

    显然的维护值域计数器。

    由于闲着没事干莽了个线段树。

    代码:

    #if 0
    长春这天下大雨,武昌这天下大雨。
    连续两天下大雨,持续两天下大雨。
    东京前天下大雨,龙华前天下大雨。
    显然今天下大雨,勿忘今天下大雨。
    双人飞天下大雨,泪雨滂沱下大雨。
    我也想他下大雨,直接让他下大雨。
    德州后天下大雨,虽然昨天下大雨。
    六月份天下大雨,后五月天下大雨。 
    #endif
    #include<bits/stdc++.h>
    using namespace std;
    int read(){
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar()))x=x*10+(ch^'0');
    	return x;
    }
    const int N=609,M=1024;
    int zkw[N<<2];
    inline void update(int x){
    	for(++zkw[x+=M];x>>=1;zkw[x]=zkw[x<<1]+zkw[x<<1|1]);
    }
    inline int query(int num){
    	register int pos=1;
    	while(pos<M){
    		if(zkw[pos<<1]>=num)pos<<=1;
    		else num-=zkw[pos<<1],pos=pos<<1|1;
    	}return pos-M;
    }
    int main(){
    	freopen("live.in","r",stdin);
    	freopen("live.out","w",stdout);
    	register int n=read(),w=read();
    	for(register int i=1;i<=n;++i){
    		update(601-read());
    		printf("%d ",601-query(max(i*w/100,1)));
    	}fflush(stdout);
    	return 0;
    }
    

    T3

    有点小难度。

    思路:维护表达式树(<-初赛内容)。

    解析字符串建表达式树部分略。

    先处理 not,在节点上打标记,然后先根遍历下放,途中 andor 互换,(0)(1) 也互换。

    然后后根遍历求出每个点对应的表达式子树的值。

    然后先根遍历,遍历到一个点的时候,如果这个点的父亲和兄弟使得表达式计算到这里时出现了和 (0) and 或者和 (1) or 就代表这个点被废弃了(无用),打个标记。

    然后先根遍历下传标记。

    最后改变一个点的值的时候,如果这个点有废弃标记,那肯定没影响。

    反之,则一定一路都是和 (1) and 或者和 (0) or,自然答案也会改变。

    代码:

    #if 0
    长春这天下大雨,武昌这天下大雨。
    连续两天下大雨,持续两天下大雨。
    东京前天下大雨,龙华前天下大雨。
    显然今天下大雨,勿忘今天下大雨。
    双人飞天下大雨,泪雨滂沱下大雨。
    我也想他下大雨,直接让他下大雨。
    德州后天下大雨,虽然昨天下大雨。
    六月份天下大雨,后五月天下大雨。 
    #endif
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+9;
    int fa[N],tot;
    int lson[N],rson[N];
    bool val[N];
    int fst[N];
    char op[N];
    bool tag[N];
    char f[N],*p=f;
    bool abded[N];
    stack<int>stk;
    int read_on_str(){
    	#define getchar() *(p++)
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar()))x=x*10+(ch^'0');
    	--p;
    	return x;
    }
    void Pr_str(){
    	gets(f);
    	while(*p){
    		while(*p==' ')++p;
    		if(*p=='x'){
    			fst[read_on_str()]=++tot;
    			stk.push(tot);
    		}else if(*p=='&'||*p=='|'){
    			op[++tot]=*(p++);
    			register int u=stk.top();stk.pop();
    			fa[u]=tot,lson[tot]=u;
    			u=stk.top();stk.pop();
    			fa[u]=tot,rson[tot]=u;
    			stk.push(tot);
    		}else{
    			++p;
    			register int u=stk.top();
    			tag[u]^=1;
    		}
    	}
    }
    #undef getchar
    int read(){
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar()))x=x*10+(ch^'0');
    	return x;
    }
    int main(){
    	freopen("expr.in","r",stdin);
    	freopen("expr.out","w",stdout);
    	Pr_str();
    	register int n=read();
    	for(register int i=1;i<=n;++i)val[fst[i]]=read();
    	for(register int i=tot;i;--i)if(tag[i]){
    		tag[lson[i]]^=1,tag[rson[i]]^=1;
    		if(op[i]=='|')op[i]='&';
    		else if(op[i]=='&')op[i]='|';
    		else val[i]^=1;
    	}	
    	for(register int i=1;i<=tot;++i){
    		if(op[i]=='|'){
    			if(val[lson[i]])abded[rson[i]]=true;
    			if(val[rson[i]])abded[lson[i]]=true;
    			val[i]=val[lson[i]]|val[rson[i]];
    		}
    		else if(op[i]=='&'){
    			if(!val[lson[i]])abded[rson[i]]=true;
    			if(!val[rson[i]])abded[lson[i]]=true;
    			val[i]=val[lson[i]]&val[rson[i]];
    		}
    	}
    	for(register int i=tot;i;--i)if(abded[i])abded[lson[i]]=abded[rson[i]]=true;
    	register char ret=val[tot]^'0';
    	for(register int q=read();q;--q){
    		putchar(ret^!abded[fst[read()]]),putchar('
    ');
    	}fflush(stdout);
    	return 0;
    }
    

    T4

    显然的 dp,状态为当前坐标和上一次从哪里走来。

    瞎转移即可,见代码。

    #if 0
    长春这天下大雨,武昌这天下大雨。
    连续两天下大雨,持续两天下大雨。
    东京前天下大雨,龙华前天下大雨。
    显然今天下大雨,勿忘今天下大雨。
    双人飞天下大雨,泪雨滂沱下大雨。
    我也想他下大雨,直接让他下大雨。
    德州后天下大雨,虽然昨天下大雨。
    六月份天下大雨,后五月天下大雨。 
    #endif
    #include<bits/stdc++.h>
    using namespace std;
    int read(){
    	register char ch;
    	register bool f=false;
    	while(!isdigit(ch=getchar()))if(ch=='-')f=true;
    	register int x=ch^'0';
    	while(isdigit(ch=getchar()))x=x*10+(ch^'0');
    	return f?-x:x;
    }
    long long dp[3][1009][1009];
    //0:从左;1:从下;2:从上;
    int val[1009][1009];
    inline long long ut_max(long long a,long long b){
    	return a>b?a:b;
    }
    inline long long ut_max(long long a,long long b,long long c){
    	return ut_max(a,ut_max(b,c));
    }
    int main(){
    	freopen("number.in","r",stdin);
    	freopen("number.out","w",stdout);
    	register int n=read(),m=read();
    	for(register int i=1;i<=n;++i)
    		for(register int j=1;j<=m;++j)
    			val[i][j]=read();
    	dp[0][1][1]=val[1][1];
    	for(int i=2;i<=n;++i)dp[0][1][i]=-1e12;
    	for(register int j=1;j<=m;++j){
    		dp[1][j][n]=dp[2][j][1]=-1e12;
    		if(j>1)for(register int i=1;i<=n;++i)
    		dp[0][j][i]=ut_max(dp[0][j-1][i],dp[1][j-1][i],dp[2][j-1][i])+val[i][j];
    		for(register int i=n-1;i;--i)
    		dp[1][j][i]=ut_max(dp[1][j][i+1],dp[0][j][i+1])+val[i][j];
    		for(register int i=2;i<=n;++i)
    		dp[2][j][i]=ut_max(dp[2][j][i-1],dp[0][j][i-1])+val[i][j];
    	}
    	printf("%lld
    ",ut_max(dp[0][m][n],dp[2][m][n]));
    	fflush(stdout);
    	return 0;
    }
    

    Over.

  • 相关阅读:
    最长递增子序列
    Mit os Lab 2. Memory Management
    [ZZ]实现c协程
    Linux socket IO模型
    emacs简单入门
    令牌桶-流量控制
    GNU Makefile tips
    Linux atomic memory access
    [zz]Linux系统相关shell命令
    state thread
  • 原文地址:https://www.cnblogs.com/unyieldingtrilobite/p/13991671.html
Copyright © 2011-2022 走看看