题目大意:
桌面上方了N 张牌,有正面朝上和反面朝上的。
然后执行两种操作,R和L
R就是把最右边的一堆牌反转一下放在右边数第二个上面
也是是
如果
A
B
D C
执行了R就是
C
B
A
D
了
那么用并查集维护他们在每个堆上的位置,用线段树维护他们的正反状态。
最后会合成一个堆,所以他们最后的位置是独一无二的,
直接找就可以了
我写的很麻烦,其实按照这个思路。直接暴力模拟就行了。数据很小。
#include#include #include #include #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e #define maxn 105 using namespace std; int tre[maxn<<2]; int set[maxn]; int pos[maxn]; int cnt[maxn]; char str[maxn]; int tcnt; int find(int x) { if(x==set[x])return x; else return set[x]=find(set[x]); } void pushdown(int num) { if(tre[num]) { tre[num<<1]^=1; tre[num<<1|1]^=1; tre[num]=0; } } void build(int num,int s,int e) { tre[num]=0; if(s==e) { tre[num]=str[tcnt]=='U' 1:0; tcnt++; return; } int mid=(s+e)>>1; build(lson); build(rson); } void update(int num,int s,int e,int l,int r) { if(l<=s && r>=e) { tre[num]^=1; return; } pushdown(num); int mid=(s+e)>>1; if(l<=mid)update(lson,l,r); if(r>mid)update(rson,l,r); } void query(int num,int s,int e,int pos,int val) { if(s==e) { if(tre[num]==0) printf("Card %d is a face down %d.",val,s); else printf("Card %d is a face up %d.",val,s); puts(""); return; } pushdown(num); int mid=(s+e)>>1; if(pos<=mid)query(lson,pos,val); else query(rson,pos,val); } int main() { int n; int CASE=1; while(scanf("%d",&n)!=EOF && n) { scanf("%s",str); tcnt=0; build(1,1,n); for(int i=1;i<=n;i++) { pos[i]=cnt[i]=1; } for(int i=1;i<=n;i++)set[i]=i; scanf("%s",str); int len=strlen(str); int cntr=0,cntl=0; for(int i=0;i