1. 程式人生 > >bzoj4534: 基礎排序演算法練習題

bzoj4534: 基礎排序演算法練習題

Description

 

 

OI小園丁ZZX最近在XJOI上夜以繼日地學習程式設計基礎知識,刷初級訓練題庫。在無壓力AC了“圓的周長與面積”、“二位數加法口算訓練程式”等題之後,他遇到了這樣一道難題:

“輸入n個數a[1], a[2], ..., a[n],請將它們升序排序後輸出。”

ZZX苦思冥想,不知所措,便去請教德高望重的OI老司機JRY。

JRY貼給他一段超自然的神祕程式碼,說:

“你把這段東西塞程序序裡,然後每次呼叫magic(left, right)這個函式,它就會用O(1)時間將a[left], a[left+1], ..., a[right]原地升序排序。”

“勁啊”

“但是啊由於一些奇怪的原因,你不能直接呼叫magic(1,n),否則程式會RE”

“wori?”

不過這難不倒聰明伶俐的ZZX。經過一番思索,他寫出了這樣一段程式:

input(a[1], a[2], ..., a[n]);

magic(left_1, right_1);

magic(left_2, right_2);

...

magic(left_m, right_m);

output(a[1], a[2], ..., a[n]);

JRY看了這段程式碼,批判道:“Native! 看我用遺傳演算法造個數據分分鐘把你卡掉”

然而ZZX並不信服,他打算把程式交到XJOI上,用評測結果來打JRY的臉。

由於XJOI管理員Ginger最近忙於打Geometry Dash,沒有工夫來修理狗帶了的評測姬。因此評測任務落到了你的頭上。

這道題共有q個測試點。你需要對於每一個測試點,判斷ZZX的程式是否輸出了正確的排序結果。

 

Input

第一行三個整數n, m, q。 接下來m行按順序給出了ZZX的程式中每條指令的引數left_i, right_i。 接下來q行,每行表示一個測試點,包含空格隔開的n個非負整數a[1], a[2], ..., a[n]。 1 ≤ n ≤ 1500 , 1 ≤ m ≤ 1000000 , 1 ≤ q ≤ 1500;  1 ≤ left_i ≤ right_i ≤ n, right_i - left_i + 1 < n; 0 ≤ a[i] ≤ 1500。

 

Output

對於每個測試點輸出一行,如果ZZX的程式能將這個數列正確排序,輸出"AC",否則輸出"WA"。

 

Sample Input

6 3 2
1 3
3 6
1 3
4 2 2 3 0 7
5 3 8 2 1 9

Sample Output

AC
WA
樣例說明
對於第一個測試點:
4 2 2 3 0 7 -> [2 2 4] 3 0 7 -> 2 2 [0 3 4 7] -> [0 2 2] 3 4 7,正確。
對於第二個測試點:
5 3 8 2 1 9 -> [3 5 8] 2 1 9 -> 3 5 [1 2 8 9] -> [1 3 5] 2 8 9,錯誤。     策爺的論文題啊…… 題解在這兒 我只想知道為啥這題的弱化版會出現在我們的NOIP模擬賽裡
 1 //minamoto
 2 #include<bits/stdc++.h>
 3 #define rint register int
 4 #define min(x,y) ((x)<(y)?(x):(y))
 5 #define ls (p<<1)
 6 #define rs (p<<1|1)
 7 #define ppd(p,v) (mn[p]+=(v),tag[p]+=(v))
 8 #define mem(a) (memset(a,0,sizeof(a)))
 9 using namespace std;
10 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
11 char buf[1<<21],*p1=buf,*p2=buf;
12 int read(){
13     int res,f=1;char ch;
14     while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
15     for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
16     return res;
17 }
18 const int N=2005,M=1e6+5;
19 int n,m,q,c[N],posc[N],b[N],posb[N],mn[N<<2],tag[N<<2];
20 struct ques{int l,r;}p[M];set<int>s;
21 struct node{
22     int val,id;
23     inline bool operator <(const node &b)const{return val==b.val?id<b.id:val<b.val;}
24 }f[N];
25 void SORT(rint l,rint r){
26     rint i;
27     while((i=*s.upper_bound(l-1))>=l&&i<r){
28         s.erase(i),swap(c[i],c[i+1]);
29         if(c[i+1]<c[i+2]&&c[i]>c[i+2])s.insert(i+1);
30         if(c[i-1]<c[i]&&c[i-1]>c[i+1])s.insert(i-1);
31     }
32 }
33 inline void pd(int p){if(tag[p])ppd(ls,tag[p]),ppd(rs,tag[p]),tag[p]=0;}
34 void update(int p,int l,int r,int ql,int qr,int v){
35     if(ql<=l&&qr>=r)return (void)(ppd(p,v));
36     int mid=(l+r)>>1;pd(p);
37     if(ql<=mid)update(ls,l,mid,ql,qr,v);
38     if(qr>mid)update(rs,mid+1,r,ql,qr,v);
39     mn[p]=min(mn[ls],mn[rs]);
40 }
41 int main(){
42 //    freopen("testdata.in","r",stdin);
43     n=read(),m=read(),q=read();
44     for(int i=1;i<=m;p[i].l=read(),p[i].r=read(),++i);
45     for(int i=1;i<=n;c[i]=i,++i);
46     for(int i=1;i<n;s.insert(i),++i);
47     for(int i=m;i;SORT(p[i].l,p[i].r),--i);
48     for(int i=1;i<=n;posc[c[i]]=i,++i);
49     while(q--){
50         for(int i=1;i<=n;f[i].val=read(),f[i].id=i,++i);
51         sort(f+1,f+1+n);
52         for(int i=1;i<=n;b[f[i].id]=i,++i);
53         for(int i=1;i<=n;posb[b[i]]=i,++i);
54         mem(mn),mem(tag);
55         bool flag=1;
56         for(int i=2;i<=n;++i){
57             update(1,1,n,posb[i-1],n,1);
58             update(1,1,n,posc[i-1],n,-1);
59             if(mn[1]<0){flag=0;break;}
60         }
61         puts(flag?"AC":"WA");
62     }
63     return 0;
64 }