日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CF1322C:Instant Noodles

發(fā)布時間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CF1322C:Instant Noodles 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

解析

神仙題了屬于是
SiS_iSi?為右側第i個點連向的左側點的集合
然后把所有SiS_iSi? 相同的點合并成一個點(就稱為新點吧),點權相加
合并后的所有點權的gcd(設為w吧)就是答案

為什么?
首先一個顯然的結論是,SiS_iSi?相同的點要么都被選到,要么都選不到
然后考慮任何一個左側點的選取方案,權值肯定是一些新點的權值和
因此w也一定是這個方案權值的因子
w的合法性得以證明

然后是w的最優(yōu)性
考慮假設有一個x,是比w更大的符合的答案
那么一定至少存在一個新點k,使x不是它的因子了
那么考慮當選取的集合為SkS_kSk?的時候都權值和
如果這個權值和仍是x的倍數(shù),說明至少存在一個新點k′k'k,使Sk′S_{k'}Sk?SkS_{k}Sk?的子集,且k’的權值也不是x的倍數(shù)(這樣他們加起來才可能是x的倍數(shù))
那么把k’作為新的k,遞歸到考慮選取集合為Sk′S_{k'}Sk?的情況
這樣集合會越來越小,直到無法找出新的k’為止,就一定能找到一種方案,使x不是該方案權值的因子
最優(yōu)性得以證明

思路有了以后,代碼實現(xiàn)就不難了
我偷懶沒有用哈希,使用的是map套vector

#include<bits/stdc++.h> using namespace std; #define ll long long const int N=5e5+100; ll read() {ll x=0,f=1;char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=x*10+(c^48);c=getchar();}return x*f; }int n,m; #define V vector<int> V v[N]; map<V,ll>mp; map<V,ll>::iterator it; ll gcd (ll a,ll b){return b?gcd(b,a%b):a; } ll a[N]; int main() { #ifndef ONLINE_JUDGE//freopen("a.in","r",stdin);//freopen("a.out","w",stdout); #endifint T=read();while(T--){mp.clear();ll ans=0;n=read();m=read();for(int i=1;i<=n;i++){v[i].clear();v[i].shrink_to_fit();}for(int i=1;i<=n;i++) a[i]=read();for(int i=1;i<=m;i++){int x=read(),y=read();v[y].push_back(x);}for(int i=1;i<=n;i++){if(v[i].size()==0) continue;sort(v[i].begin(),v[i].end());mp[v[i]]=mp[v[i]]+a[i];}for(it=mp.begin();it!=mp.end();it++){ll o=(*it).second;//printf("o=%lld\n",o);ans=gcd(o,ans);}printf("%lld\n",ans);}return 0; } /* 3 501 502 503 */

總結

以上是生活随笔為你收集整理的CF1322C:Instant Noodles的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。