此次模擬賽,難度。。。還能夠吧。由於是歡樂賽,因此打的很開心node
連接ide
原本想開個桶的,而後看到了\(a_i \le 10^9\)。因而我就開了個map
優化
這算是道模擬題吧。具體看代碼,很好懂的。idea
namespace Sol{ map<int,int> m;//1e9,不現實 int n,tot,t=1,ans=inf,a[1005];//t要從1開始 inline int Main(){ n=read(); for(int i=1;i<=n;i++){ a[i]=read(); if(m[a[i]]==1) tot++;//記錄一個數的個數 m[a[i]]++; } for(int i=1;i<=n;i++){ m[a[i]]--; if(m[a[i]]==1) tot--; while(!m[a[t]]&&t<i) m[a[t++]]++; if(tot==0) ans=min(ans,i-t+1); } printf("%d",ans==1?0:ans);//ans=1,表示沒有刪減 return 0; } }
連接spa
一道數學題。找規律便可。code
咱們必定知道,全部數的倍數的個位數是會循環的~~blog
例如:排序
2:2 4:4 6:6 8:8 10:0 12:2 .... 3:3 6:6 9:9 12:2 15:5 18:8 21:1 24:4 27:7 30:0 33:3...... //以此類推
題目讓求的是 求 \(1 \sim n\) 的全部整數中,能被 \(m\) 整除的整數的個位數字之和 。get
咱們發現了個位數字是循環的,因而咱們就靠這個來優化。數學
發現:當\(x\%10=0\)時 ,\(x\)爲\(m\)的倍數,一輪循環結束。計算這輪循環的答案\(Ans\)
而後咱們判斷\(1 \sim n\)中有多少個\(x\)。假設有\(a\)個,則這\(a\)組的值爲\(a \times Ans\)。
最後計算餘下的數中個位之和便可。講的不是很清,你們本身手玩幾組就知道了。
能夠藉助代碼理解哦~~
namespace Sol{ int ans; inline int Main(){ int T=read(); while(T--){ int n=read(),m=read(); ans=0; for(int i=m;i<=n;i+=m){ if(i%10==0){ ans*=n/i;//n/i是看有多少組,而後就能夠跳過這n/i組 i*=n/i;//跳到了i*=n/i這個數 } ans+=i%10;//計算個位和 } printf("%lld\n",ans); } return 0; } }
knapsack?好奇怪的名字
這道題,是個\(DP\)?仍是我能寫的那種
這道題按\(out\)爲第一關鍵字,\(in\)爲第二關鍵字排序。
即先把全部物品按照拿走的時間從小到大排序,拿走的時間相同就按照放上去的時 間從大到小。那麼一件物品上方的物品就必定會在它的前面。
這裏設 \(f[i][j]\)表示\(i\) 以及\(i\) 上面的物品在全部時刻中最大重量爲 \(j\) 時的最 大收益。
轉移的時候,枚舉全部 \(i\) 上面的物品,維護一個 \(g[i]\)表示時刻 \(i\) 以前 物品的最大收益是多少。而後轉移。
目標\(f[n][S]\)
真的很簡單
namespace Sol{ struct node{ int in,out,w,s,v; }a[505]; int f[505][maxn],g[maxn]; int n,S; inline bool cmp(node a,node b){ if(a.out==b.out) return a.in>b.in; return a.out<b.out; } inline int Main(){ n=read(); S=read(); for(int i=1;i<=n;i++) a[i]=(node){read(),read(),read(),read(),read()}; a[++n]=(node){0,n*2,0,S,0}; sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++) for(int w=a[i].w;w<=S;w++){ int x=a[i].in; g[x]=0; int y=min(w-a[i].w,a[i].s); for(int j=1;j<i;j++) if(a[j].in>=a[i].in){ while(x<a[j].out)x++,g[x]=g[x-1]; g[x]=max(g[x],g[a[j].in]+f[j][y]); } f[i][w]=g[x]+a[i].v; } printf("%d",f[n][S]); return 0; } }
一道 狀壓。又是狀壓,草
這裏上題解。由於我太菜了,不會解釋
考慮這個題其實就是給咱們若⼲個⼆進制數,問最終有多少種選數的⽅案使得or(即\(\oplus\)異或)起來所有是1。
令\(cnt(S)\)表示等於\(S\)的⼆進制數個數,令\(f(S)=\displaystyle \sum_{S' \subseteq S}cnt(S')\) ,那麼⼀個顯然的容斥有答案爲\(\displaystyle \sum_{S} 2^{f(S)} (-1)^{n-\mid S \mid}\)
因此惟⼀的難點在於怎麼求\(f(S)\),若是直接暴⼒求複雜度是\(3^M\),能夠得到\(70\ pts\)。 這其實就是⼀個⾼維前綴和問題。令\(f_{i,j}\)爲在不考慮前\(i\)位的狀況下,\(j\)的前綴和。 ⾸先,顯然有\(f_{i,j}=cnt_{i}\) ,其次\(f_{i,j}=f_{i+1,j}+f_{j \mid (1<<i)}\),其中\(j\)的第\(i\)位是0. 直接⼀個遞推就作完了
\(\mathcal {P.S:}\)注意爆負。
namespace Sol{ int f[maxn],g[maxn],s[maxn],a[maxn]; inline int Main(){ int n=read(),m=read(); a[0]=1; for(int i=1;i<=n;i++){ int x=read(); for(int j=1;j<=x;j++) s[i]+=(1<<(read()-1)); g[s[i]]++; a[i]=(a[i-1]<<1)%mod; } for(int j=0;j<m;j++) for(int i=0;i<(1<<m);i++) if(i&(1<<j)) g[i]+=g[i-(1<<j)]; for(int i=0;i<(1<<m);i++) f[i]=a[g[i]]; for(int j=0;j<m;j++) for(int i=0;i<(1<<m);i++) if(i&(1<<j)) f[i]=((f[i]-f[i-(1<<j)])%mod+mod)%mod; printf("%d",f[(1<<m)-1]); return 0; } }
\[ The \quad End \]
\[ \text{我獨酌山外小閣樓,窗外漁火如豆。江畔晚風拂柳,訴盡離愁。當月色暖小樓,是誰又在彈奏那一曲思念常(長)留-《山外小樓夜聽雨》易碩成} \]