[考試反思]1001csp-s模擬測試(b):逃離


如你所見,b組題,除了NC亂入直奔T2搶了我一個首殺以外A層學過FFT的人都沒有參加。

競爭壓力很小,題又簡單,所以就造就了6個AK。

然而並不計入總分,我仍然穩在第二機房。

T1lyl16分鍾切掉我也是佩服,我沒看數據范圍打錯復雜度(多了個二分)23分鍾碼完,T30。

思路都不是很毒瘤,代碼也很好打,加起來都沒有2k。

47分鍾時干掉T3后我覺得差不多AK了,去廁所聽到隔壁聽講FFT的聲音,有些難過。

回來之后打開題庫翻看FFT的題目看了半個小時左右。

然后自覺無聊,重新算了一下T1復雜度發現會被卡,改了。

過了一會,教練叫我去隔壁聽了一會講。。。

因為T1的失手導致了少聽了33分鍾的課。。。吸取教訓

一定要認真算好復雜度再開始打。

 

T1:X國的軍隊

考慮貪心並逆推。把b數組都減去a數組的量表示戰后至少剩下多少人。

考慮每個任務放進優先隊列里,只要戰后剩余人數足夠就繼續,否則就補人。

 1 #include<cstdio>
 2 #include<queue>
 3 using namespace std;
 4 priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
 5 int a[100005],b[100005];
 6 int read(){
 7     register int p=0;register char ch=getchar();
 8     while(ch>'9'||ch<'0')ch=getchar();
 9     while(ch<='9'&&ch>='0')p=(p<<3)+(p<<1)+ch-'0',ch=getchar();
10     return p;
11 }
12 int main(){
13     int t=read();
14     while(t--){
15         int n=read();long long tot=0,now=0,ex=0;
16         for(int i=1;i<=n;++i)a[i]=read(),b[i]=read(),tot+=a[i],q.push(make_pair(b[i]-a[i],i));
17         while(!q.empty()){
18             int x=q.top().first;
19             if(x>now)ex+=x-now,now=x;
20             now+=a[q.top().second],q.pop();
21         }
22         printf("%lld\n",ex+tot);
23     }
24 }
View Code

 

T2:排列組合

考慮式子的實際含義,把每一項的第二個組合數改寫一下就是$\sum\limits_{i=0}^{n}C_n^i C_n^{n-i}$

那么就是在2n個物品里選n個的全部可能。

數組開2倍。肯定有人出鍋了。

 1 #include<cstdio>
 2 #define int long long 
 3 #define mod 1000000007
 4 int fac[2000005],invv[2000005],inv[2000005];
 5 main(){
 6     int t,n;scanf("%lld",&t);
 7     inv[0]=inv[1]=invv[1]=fac[0]=fac[1]=1;
 8     for(int i=2;i<=2000000;++i)fac[i]=fac[i-1]*i%mod,invv[i]=mod-mod/i*invv[mod%i]%mod,inv[i]=inv[i-1]*invv[i]%mod*invv[i]%mod;
 9     while(t--)scanf("%lld",&n),printf("%lld\n",fac[n<<1]*inv[n]%mod);
10 }
View Code

 

T3:回文

發現串長很小,准備亂搞。

可以S2處理所有回文串。暴力即可。記錄每一個回文串的兩端點。

每次詢問就是求有多少個回文串左端點比L大右端點比R小。

普通的二維偏序,值域只有5000*5000,樹狀數組解決。

 1 #include<cstdio>
 2 int l,t[5005][5005];char s[5005];
 3 void add(int x,int y){for(;x<=l;x+=x&-x)for(int j=y;j<=l;j+=j&-j)t[x][j]++;}
 4 int ask(int x,int y,int a=0){for(;x;x-=x&-x)for(int j=y;j;j-=j&-j)a+=t[x][j];return a;}
 5 int main(){
 6     scanf("%s",s+1);while(s[l+1])l++;
 7     for(int i=1;i<=l;++i)for(int j=0;j<i&&i+j<=l;++j)if(s[i-j]==s[i+j])add(l+1-(i-j),i+j);else break;
 8     for(int i=1;i<l;++i)for(int j=0;j<i&&i+j+1<=l;++j)if(s[i-j]==s[i+j+1])add(l+1-(i-j),i+j+1);else break;
 9     int t,L,R;scanf("%d",&t);while(t--)scanf("%d%d",&L,&R),printf("%d\n",ask(l+1-L,R));
10 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM