csp-s analog test 53u, v, w Interpretations

Questions surface: https://www.cnblogs.com/Juve/articles/11602450.html

in:

Optimization modified by difference

Dimensional difference: to (x1, y1), (x2, y2) plus s:

$d[x1][y1]+=s,d[x1][y2+1]-=s,d[x2+1][y1]-=s,d[x2+1][y2+1]+=s$

Defines an array of two differential d1, d2, respectively, and recording the differential vertical column hypotenuse

$d1[r][c]+=s,d1[r+l-1][c]-=s,d2[r][c+1]-=s,d2[r+l-1][c+l-1]+=s$

Statistics are seeking two prefixes and

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int MAXN=1e3+5;
int n,q,a[MAXN][MAXN],b[MAXN][MAXN],c[MAXN][MAXN],d[MAXN][MAXN],ans=0;
int d1[MAXN][MAXN],d2[MAXN][MAXN];
signed main(){
	scanf("%lld%lld",&n,&q);
	while(q--){
		int r,c,l,s;
		scanf("%lld%lld%lld%lld",&r,&c,&l,&s);
		int N=min(n,r+l-1),M=min(n,c+l-1);
		d1[r][c]+=s,d1[N+1][c]-=s;
		d2[r][c+1]-=s,d2[N+1][M+2]+=s;
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j){
			a[i][j]=(a[i-1][j]+d1[i][j]);
			b[i][j]=(b[i-1][j-1]+d2[i][j]);
			c[i][j]=a[i][j]+b[i][j];
			d[i][j]=d[i][j-1]+c[i][j];
		}
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j)
			ans^=d[i][j];
	}
	printf("%lld\n",ans);
	return 0;
}

 

v:

 

Search every case, the repeated use of bit map memory

Note that a length of an odd number is determined, map timeout hash table can be used

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define re register
using namespace std;
int n,k,sta=0;
char ch[35];
struct hash_map{
	int pre[40000000],cnt;
	struct node{
		int nxt,to,w;
		double v;
	}e[6000000];
	double &operator[](int sta){
		int key=1LL*sta%30000019;
		for(int i=pre[key];i;i=e[i].nxt)
			if(e[i].to==sta) return e[i].v;
		e[++cnt].nxt=pre[key];e[cnt].to=sta;;e[cnt].v=-1.0;
		pre[key]=cnt;
		return e[cnt].v;
	}
}mp;
inline double dfs(re int x,re int st){
	if(x==n-k) return 0.0;
	if(mp[st]!=-1) return mp[st];
	mp[st]=0;
	re double sum=0.0;
	for(re int i=1;i<=x>>1;i++){
        re int con1=st>>i-1&1,con2=st>>x-i&1;
        re int to1=st>>1&~((1<<i-1)-1)|st&(1<<i-1)-1;
        re int to2=st>>1&~((1<<x-i)-1)|st&((1<<x-i)-1);
        sum+=2.0*max(dfs(x-1,to1)+con1,dfs(x-1,to2)+con2)/x;
    }
    if(x&1){
        re int i=x+1>>1;
        re int to=st>>1&~((1<<i-1)-1)|st&(1<<i-1)-1;
        re int con=st>>i-1&1;
        sum+=(dfs(x-1,to)+con)/x;
    }
    return mp[st]=sum;
}
signed main(){
	scanf("%d%d",&n,&k);
	scanf("%s",ch+1);
	for(re int i=1;i<=n;i++)
        sta|=(ch[i]=='W')<<n-i;
    sta|=1<<n;
	printf("%0.7lf\n",dfs(n,sta));
	return 0;
}

 

w:

If we choose a side, give the degree of edge points at both ends plus one, then the first answer is that the degree is odd number of points divided by 2

We define dp [i] [0/1] represent the i-node, no / There are two answers to his father's side of the reverse i

Next we consider the update:
when updating we use two parameters: p and q, dp updated as intermediate step, do not chain to i p represents an endpoint, q i do representative chain end, a certain set i child node is to, so there are:
P = min (P + DP [to] [0], Q + DP [to] [. 1])
Q = min (P + DP [to] [. 1], Q + DP [ to] [0])
wherein p is initialized to (0,0), q is initialized (INF, INF)
explain: here the Add pair corresponding element is added (non-built-in handwriting)!!
and operating means press the pair min comparing the first key, then press the second key comparison
then this step is a combined process:
first of all, i do not chain as an endpoint: to combine two types: If the edges of the child nodes and i flipped, then they would i was tired at the end of the chain to the inside (because i do not flip side with his father, then i will be the endpoints), if the child node and edge i is not turned over, only for the purposes of sub-tree tree, and not as i end path, so there is no update to the expense i endpoint chain
if the chain as an end point i, to merge the two types of the same: if the edge node i flip child, then obviously i May be the end of the chain, provided that this is not a chain before the end i, so i is not used before the end of the chain to the cost of updating; on the contrary, if the child node and edge i is not turned over, that matter is not i endpoint is an endpoint may request i chain, so i have to use the cost of the original chain of endpoints is updated
after traversing the root of all child nodes, update dp:
if i do not flip side with his father. That state dp [i] [0]:
First, as an endpoint chain not i is certainly a possibility, direct comparison
and then, if i is an endpoint of the chain, the edge node i and the parent has not turned over, described in this state i is the real point of singularity, so the first + q status update 1
if i and father's side flip, the same two types of updates:
First of all, i itself as the endpoint of the chain, and because i itself is a singular degree point, it will only be updated q.second + 1 can
also, if i did not own in the following chain as an endpoint, but i did side with the parent node occurs flip, so i became a new point of singularity, while also increasing the chain length, so p.first, p.second were increased to
the final answer is, dp [1] [0] .first / 2, dp [1] [0] .second

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN=5e5+5;
const int inf=0x3f3f3f3f;
int n;
int to[MAXN<<1],nxt[MAXN<<1],pre[MAXN],flag[MAXN<<1],cnt=0;
void add(int u,int v,int val){
	++cnt,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt,flag[cnt]=val;
}
struct node{
	int tim,len;
	friend node operator + (node a,node b){
		return (node){a.tim+b.tim,a.len+b.len};
	}
	friend bool operator < (node a,node b){
		return a.tim==b.tim?a.len<b.len:a.tim<b.tim;
	}
}dp[MAXN][2];
node min(node a,node b){
	return a<b?a:b;
}
void dfs(int x,int fa,int fl){
	node p={0,0},q={inf,inf};
	for(int i=pre[x];i;i=nxt[i]){
		int y=to[i];
		if(y==fa) continue;
		dfs(y,x,flag[i]);
		node a=p,b=q;
		p=min(a+dp[y][0],b+dp[y][1]);
		q=min(b+dp[y][0],a+dp[y][1]);
	}
	if(fl==2){
		dp[x][0]=min(p,q+(node){1,0});
		dp[x][1]=min(p+(node){1,1},q+(node){0,1});
	}
	if(fl==1){
		dp[x][0]=(node){inf,inf};
		dp[x][1]=min(p+(node){1,1},q+(node){0,1});
	}
	if(fl==0){
		dp[x][0]=min(p,q+(node){1,0});
		dp[x][1]=(node){inf,inf};
	}
}
signed main(){
	scanf("%d",&n);
	for(int i=1,a,b,c,d;i<n;++i){
		scanf("%d%d%d%d",&a,&b,&c,&d);
		if(d==2){
			add(a,b,2),add(b,a,2);
		}else{
			if(c==d) add(a,b,0),add(b,a,0);
			else add(a,b,1),add(b,a,1);
		}
	}
	dfs(1,0,0);
	printf("%d %d\n",dp[1][0].tim/2,dp[1][0].len);
	return 0;
}

 

Guess you like

Origin www.cnblogs.com/Juve/p/11602486.html