題目大意:
桌面上方了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