好慌啊 0分??node
T1ios
感受是組合數,不知道對不對。數組
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<cmath> #include<ctime> using namespace std; const int P=1e9+7; long long n,k,ans=1; int main() { freopen("cube.in","r",stdin); freopen("cube.out","w",stdout); scanf("%lld%lld",&n,&k); int x; for(int i=1;i<=n;i++) scanf("%d",&x); for(int i=k+1;i<=n;i++) ans=(ans*i)%P; for(int i=2;i<=(n-k);i++) ans=(ans*i)%P; cout<<ans<<'\n'; return 0; }
完了組合數用錯了,應該用逆元的。ide
思路:
其實就是說,在n個位置中,找出K個與原來不一樣的(1或0兩種)。spa
組合數公式n! / k!(n-k)! 由於數比較大,若是先取模再除 是不對的。code
用乘法逆元,/x %p等價於 *x^P-2 .blog
也能夠分解質因數,不知道哪根筋抽了,這都沒想到。 字符串
T2 string
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<cmath> using namespace std; const int N=1e5+100; int n,m,q; struct node{ int x,y; int z; }a[N],ask[N]; int f[N],tot; int find(int x) { while(x!=f[x]) x=f[x]=f[f[x]]; return x; } bool cmp(node u,node v) { return u.z>v.z;} bool fan(node u,node v) { return u.y<v.y;} int main() { freopen("warehouse.in","r",stdin); freopen("warehouse.out","w",stdout); scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); for(int i=1;i<=q;i++) scanf("%d",&ask[i].z),ask[i].y=i; sort(a+1,a+1+n,cmp);sort(ask+1,ask+1+q,cmp); for(int i=1;i<=n;i++) f[i]=i; tot=n;int ed=0,i=1,f1,f2; for(i=1;i<=q;i++) { while(a[ed+1].z>=ask[i].z) { ed++; f1=find(a[ed].x);f2=find(a[ed].y); if(f1!=f2) { f[f1]=f2;tot--; } } ask[i].x=tot; } sort(ask+1,ask+q+1,fan); for(int i=1;i<=q;i++) printf("%d\n",ask[i].x); return 0; }
應該寫對了啊,0分。。。it
和昨天的題差很少,建一個最大生成樹,在合併的過程當中更新答案。
T3
不會去重,甚至計數都不會。
這道題的確不簡單,由於一個字符串可能會獲得屢次,
那咱們就就想辦法讓這個字符串只獲得一次,怎麼操做那?
維護兩個數組a[i][j](表示長度爲i的前綴,後面再加j字符就會重複的字符串數量)
c[i][j](表示以j爲開頭,長度爲i的字符串數量)
(由於咱們只須要考慮,字符串長度,和是否重複)
最後把長度和爲L的前綴和後綴字符根據乘法原理組合起來就是答案了。
可是!這樣作有漏洞!!
緣由是對於原本就是一個單詞一部分的字符如coo,它能由co 前綴和 o後綴 組成,但咱們卻沒有斷定出co這個前綴。