[NOIP Simulation Test]: bit arithmetic (math)

Topic Portal (internal title 12)


Input Format

The first row, three integer $ n, m, c $, meaning described above.
Second row, $ n-1 $ string, the first string of $ I $ $ {opt} _i $ $ I $ th represents the operator.
Third row, n-$ $ integers, the first integer $ I $ $ $ x_i a_i $ $ beautiful Representative values.


Output Format

If the program, output $ $ integers n-exist, the $ I $ $ integer representing $ x_i, separated by a space between the integer. If there is a variety of programs, either of which is output. If there is no program, output $ OvO $.


Sample

Sample input 1:

4 2 3
XOR AND OR
2 1 1 1

Sample output 1:

3 2 1 2

Sample input 2:

50 6 58
AND AND XOR AND AND OR AND XOR XOR AND XOR AND XOR OR XOR OR XOR OR OR XOR OR XOR XOR AND XOR OR AND AND XOR XOR AND XOR OR OR XOR XOR AND XOR XOR AND OR XOR XOR XOR AND XOR XOR XOR XOR
3 2 5 5 3 3 1 3 3 2 3 1 3 1 5 2 5 2 3 5 2 3 5 2 4 5 2 3 2 4 3 2 3 3 0 4 1 2 2 3 6 5 2 2 2 2 3 4 3 5

Sample Output 2:

7 3 61 62 7 7 16 19 28 48 7 8 7 8 31 48 47 48 35 31 10 21 62 12 57 62 3 11 12 15 56 5 38 35 0 60 32 3 20 56 63 47 48 48 48 36 7 60 56 61


Data range and tips

Sample 1 explanation:

$ 3 \ XOR \ 2 \ AND \ 1 \ OR \ 2 = 3 $, $ and $ x_i values ​​satisfy the constraint, a combination method is solution.

data range:

For all data, $ 1 \ leqslant n \ leqslant {10} ^ 5,0 \ leqslant a_i \ leqslant m \ leqslant 30 $.


answer

Quietly look at the data range, large $ n $, but only $ 30 $ m $ $.

Then we can find, in fact, and specific values ​​does not matter, only the lower bits and the number of $ 1 $ concerned.

So we first consider whether there are solutions of the problem, set $ dp [i] [j] $ indicate whether there may be $ j $ a $ 1 $ operation result obtained after $ i $ op in the front.

May assume $ X \ opt \ Y = S $, there $, x, y, z $ a $ 1 $ are the set $ X, Y, S $ binary bits, there are $ W $ the set $ X \ & Y $ a $ 1 $, then it is divided into three cases:

  $\alpha.AND:s=w,w\leqslant x,w\leqslant y,x+y−w\leqslant m$

  $\beta.OR:s=x+y−w,w\leqslant x,w\leqslant y,x+y−w\leqslant m$

  $\gamma.XOR:s=x+y−2w,w\leqslant x,w\leqslant y,x+y−w\leqslant m$

So we only need to look at $ dp [n] [c] $ whether it is $ 1 $ can be.

Let's think feasible case (after all data points are not $ OvO $), set $ pre [i] [j] $ denotes the calculation result obtained after $ I $ op in the front with a $ J $ a $ 1 $ is after the former $ i-1 $ a calculation of how many $ 1 $ transferred from, you might ask, could have a good variety of circumstances can be transferred over, then how do? In fact, we only need one case, so we just need to record A method of transferring.

So the answer to how to calculate it?

We might as well use the $ BFS $, $ pos $ pass two parameters indicating the current position calculated, $ state $ shows the results after the current calculation.

For convenience, set: $ pre \ opt \ now = state $.

So we now know the results of this calculation step, the result of a calculation in a few $ 1 $ (temporarily set $ y_i $) and $ x_i $, looks enough, but bite the bullet and push down will find out more than enough.

  $\alpha.AND:$我们可以这样想,先使$pre$和$now$凑出$state$中所有的$1$,然后多出来的不要重复就好啦,实现起来也非常简单。

  $\beta.OR:$我的思路就是,$pre$从前枚举所有$state$的$1$,$now$从后往前枚举所有$state$的$1$,为什么这样是正确的呢?因为我们走到这一步,已经保证了答案的合法,所以这么肆无忌惮的操作一定是可行的。

  $\gamma.XOR:$依然是枚举$state$中的$1$,然后看$x_i$和$y_i$谁更大,用大的去填$state$中的$1$,填完之后只要选一样的$1$即可,那么你还可能会问,如果填完之后$x_i$和$y_i$不一样怎么办呢?还是上面的那句话,路都走到这儿了,结果肯定合法。

我们就这样,一步一步的往前找就能找到答案啦,然后倒序输出即可。

时间复杂度:$\Theta(n\times m^2)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/extc++.h>
using namespace std;
int n,m,c,x;
int pre[200001][50];
int cz[200001],a[200001];
bitset<50> bit;
bool vis[50];
void getans(int pos,int state)
{
	if(pos==1){printf("%d ",state);return;}
	bit=state;
	int gs=bit.count();
	int x=pre[pos][gs];
	int y=a[pos];
	int pr=0;
	int nw=0;
	memset(vis,0,sizeof(vis));
	switch(cz[pos])
	{
		case 1:
			for(int i=0;i<m;i++)if(state&(1<<i)){vis[i]=1;x--;y--;pr|=(1<<i);nw|=(1<<i);}
			for(int i=0;i<m&&x;i++)if(!vis[i]){x--;pr|=(1<<i);vis[i]=1;}
			for(int i=0;i<m&&y;i++)if(!vis[i]){y--;nw|=(1<<i);}
			break;
		case 2:
			for(int i=0;i<m&&x;i++)if(state&(1<<i)){x--;pr|=(1<<i);}
			for(int i=m-1;i>=0&&y;i--)if(state&(1<<i)){y--;nw|=(1<<i);}
			break;
		case 3:
			for(int i=0;i<m;i++)if(state&(1<<i)){if(x>y){x--;vis[i]=1;pr|=(1<<i);}else{y--;vis[i]=1;nw|=(1<<i);}}
			for(int i=0;i<m&&x&&y;i++)if(!vis[i]){x--;y--;pr|=(1<<i);nw|=(1<<i);}
	}
	getans(pos-1,pr);
	printf("%d ",nw);
}
int main()
{
	scanf("%d%d%d",&n,&m,&c);
	bit=c;
	x=bit.count();
	for(int i=2;i<=n;i++)
	{
		char opt[5];
		scanf("%s",opt+1);
		switch(opt[1])
		{
			case 'A':cz[i]=1;break;
			case 'O':cz[i]=2;break;
			case 'X':cz[i]=3;break;
		}
	}
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	memset(pre,-1,sizeof(pre));
	pre[1][a[1]]=0;
	for(int i=2;i<=n;i++)
		for(int j=0;j<=m;j++)
			if(pre[i-1][j]!=-1)
				switch(cz[i])
				{
					case 1:for(int k=max(a[i]+j-m,0);k<=min(a[i],j);k++)pre[i][k]=j;break;
					case 2:for(int k=max(a[i],j);k<=min(a[i]+j,m);k++)pre[i][k]=j;break;
					case 3:for(int k=abs(j-a[i]);k<=min(j+a[i],2*m-j-a[i]);k+=2)pre[i][k]=j;break;
				}
	getans(n,c);
	return 0;
}

rp++

Guess you like

Origin www.cnblogs.com/wzc521/p/11370302.html