CF1545X Codeforces Round #732

A. AquaMoon and Strange Sort

叉人題

如果數字各不相同,只需要統計每個數參與構成的逆序對總數,如果是奇數一定最終朝左,偶數朝右。無意義的數字交換對方向是沒有影響的

繼續考慮相同數字帶來的影響。逆序對考慮的交換次數是最小交換,是保守排序,相同數字的相對位置不變。把交換次數的序列按奇偶提取出來,比如001110 001100。每次操作交換兩個數字然後把它翻轉,那麼只有對相同的相鄰數進行操作纔有意義。

模型轉化爲給一個01序列,每次選擇兩個相鄰的相同數,把它們翻轉,問最後能否化成全0序列。

100100也是可行的。100100->111111->000000

把序列想象成多個連續的01段拼接。偶數段是可以任意轉化的,對答案不產生影響,能把左右直接相連。奇數段則不行,需要把它壓成一個數。用棧來考慮這個問題,如果是偶數段,什麼也不插入,如果是奇數段,會插入一個0/1,如果棧尾和新插入的元素相同,說明能合併,如果不同就推進棧尾。在最終的棧中,如果棧空或者只有一個0,則合法,其他情況我們處理不掉1,均不合法。

 1 #include <vector>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define ll long long 
 6 using namespace std;
 7 const int maxn=1e5, N1=maxn+5;
 8 
 9 template <typename _T> void read(_T &ret)
10 {
11     ret=0; _T fh=1; char c=getchar();
12     while(c<'0'||c>'9'){ if(c=='-') fh=-1; c=getchar(); }
13     while(c>='0'&&c<='9'){ ret=ret*10+c-'0'; c=getchar(); }
14     ret=ret*fh;
15 }
16 
17 int n,T,ma;
18 int a[N1],num[N1];
19 vector<int>to[N1];
20 int stk[N1],tp;
21 
22 struct BIT{
23 int sum[N1];
24 void upd(int x,int w){ for(int i=x;i<=ma;i+=i&(-i)) sum[i]+=w; }
25 int query(int x){ int ans=0; for(int i=x;i;i-=i&(-i)) ans+=sum[i]; return ans; }
26 void clr(){ for(int i=0;i<=ma;i++) sum[i]=0; }
27 }s;
28 
29 int main()
30 {
31     // freopen("a.in","r",stdin);
32     scanf("%d",&T);
33     while(T--){
34     
35     scanf("%d",&n); ma=0;
36     for(int i=1;i<=n;i++) read(a[i]), ma=max(a[i],ma);
37     for(int i=1;i<=n;i++)
38     {
39         num[i]=s.query(ma)-s.query(a[i]);
40         s.upd(a[i],1);
41     }
42     s.clr();
43     for(int i=n;i>=1;i--)
44     {
45         num[i]+=s.query(a[i]-1);
46         s.upd(a[i],1);
47         to[a[i]].push_back(num[i]&1);
48     }
49     s.clr();
50     int fl=1;
51     for(int k=1;k<=ma;k++)
52     {
53         tp=0;
54         for(int i=0,j;i<to[k].size();)
55         {
56             for(j=i;j<to[k].size() && to[k][j]==to[k][i];j++);
57             if((j-i)&1)
58             {
59                 if(!tp) stk[++tp]=to[k][i];
60                 else if(stk[tp]==to[k][i]) tp--; 
61                 else stk[++tp]=to[k][i];
62             }
63             i=j;
64         }
65         if(tp>1||(tp==1&&stk[tp]==1)) fl=0;
66         to[k].clear(); tp=0;
67     }
68     puts(fl?"YES":"NO");
69         
70     }
71     return 0;
72 }
View Code

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章