【Codeforces】Round #523 (Div. 2) A-F
A. Coins
貪心選儘量大的填
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,s,ans;
int main(){
int i,j,mx;
scanf("%d%d",&n,&s);
for(i=min(n,s);i && s;--i) if(s>=i){
ans+=s/i;s%=i;
}
printf("%d",ans);
}
B. Views Matter
離散化高度後,判斷每兩個高度間隔之間的列數,貪心先沿著對角線往後填,不夠的強制填到這個高度的最後一列。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+10; int n,m,a[N],vs[N],op,mx; ll ans,ss; int main(){ int i,j,k,mx=0,dc=0,dir=1; scanf("%d%d",&n,&m); for(i=1;i<=n;++i){ scanf("%d",&a[i]);ss+=a[i]; } sort(a+1,a+n+1); mx=a[n];k=0; for(i=j=1;i<=n;i=j){ for(;j<=n && a[j]==a[i];++j); dir+=min(n-dir+1,a[i]-dc); ans+=a[i]-dc+max(0,j-dir); dc=a[i];dir=max(dir,j); } printf("%I64d",ss-ans); return 0; }
C. Multiplicity
列舉之後設為長度為的陣列方案即可。
#include<bits/stdc++.h> const int inf=1886417009; using namespace std; typedef long long ll; const int N=510,M=1e6+10; int n,m,inn,ott,val[N],S,T,vs[N],tim,sum; int head[N<<1],to[M],nxt[M],w[M],cc[M],tot=1; int cur[N<<1],dis[N<<1],stk[N],top; inline void fl(){printf("-1");exit(0);} inline void lk(int u,int v,int flw,int cst) { to[++tot]=v;nxt[tot]=head[u];head[u]=tot;w[tot]=flw;cc[tot]=cst; to[++tot]=u;nxt[tot]=head[v];head[v]=tot;w[tot]=0;cc[tot]=-cst; } struct Gra{ int head[N],to[N],nxt[N],tot,rt; int dmd[N],col[N],dl[N]; inline void lk(int u,int v) { to[++tot]=v;nxt[tot]=head[u];head[u]=tot; to[++tot]=u;nxt[tot]=head[v];head[v]=tot; } void dfs(int x,int fa) { int i,j; for(i=head[x];i;i=nxt[i]){ j=to[i];if(j==fa) continue; dfs(j,x); } stk[++top]=x;if(!dmd[x]) return; for(i=1;i<=top;++i) col[stk[i]]=x; for(i=1;i<top;++i) dl[x]-=dmd[stk[i]]; if(dl[x]<0) fl();top=0; } }A,B; priority_queue<Pr>que; inline bool spfa() { memset(dis,0x8f,sizeof(dis)); f } int main(){ int i,j,x,y,z; scanf("%d%d%d",&n,&A.rt,&B.rt);S=(n<<1)+1;T=S+1; for(i=1;i<=n;++i) scanf("%d",&val[i]); for(i=1;i<n;++i){scanf("%d%d",&x,&y);A.lk(x,y);} for(i=1;i<n;++i){scanf("%d%d",&x,&y);B.lk(x,y);} for(scanf("%d",&z);z;--z) {scanf("%d%d",&x,&y);A.dmd[x]=A.dl[x]=y;} for(scanf("%d",&z);z;--z) {scanf("%d%d",&x,&y);B.dmd[x]=B.dl[x]=y;} A.dfs(A.rt,0);B.dfs(B.rt,0); for(i=1;i<=n;++i) if(A.dl[i]) lk(S,i,A.dl[i],0),inn+=A.dl[i]; for(i=1;i<=n;++i) if(B.dl[i]) lk(i+n,T,B.dl[i],0),ott+=B.dl[i]; if(inn!=ott) fl(); for(i=1;i<=n;++i) lk(A.col[i],n+B.col[i],1,val[i]); for(;spfa();) for(vs[T]=tim;vs[T]==tim;){ ++tim;memcpy(cur,head,sizeof(cur));inn-=dfs(S,inf); } if(inn!=0) fl(); printf("%d",sum); return 0; }
D. TV Shows
先按排序,用線段樹記錄所有沒有後繼的區間的值。
每加入一段區間首先線上段樹上二分查詢最大的的,判斷接或不接的最小花費。
By ccosi, contest: Codeforces Round #523 (Div. 2), problem: (D) TV Shows, Accepted, #
#include<bits/stdc++.h>
#define mid ((l+r)>>1)
#define lc k<<1
#define rc k<<1|1
using namespace std;
typedef long long ll;
const int N=1e5+10,mod=1e9+7;
int n,a,b,m,rv[N<<1],cnt,tot;
int ans,ss[N<<3];
struct P{
int l,r;
bool operator<(const P&ky)const{
return l<ky.l;
}
}le[N];
struct Q{
int v,id,sd;
bool operator<(const Q&ky)const{
return v<ky.v;
}
}q[N<<1];
int ask(int k,int l,int r,int R)
{
if(!ss[k]) return 0;
if(l==r) return l;int re=0;
if(R>mid) re=ask(rc,mid+1,r,R);
if(!re) re=ask(lc,l,mid,R);
return re;
}
void ad(int k,int l,int r,int pos,int vv)
{
ss[k]+=vv;
if(l==r) return;
if(pos<=mid) ad(lc,l,mid,pos,vv);
else ad(rc,mid+1,r,pos,vv);
}
int main(){
int i,j,x,y;
scanf("%d%d%d",&n,&a,&b);
for(i=1;i<=n;++i){
scanf("%d%d",&x,&y);
q[++cnt]=(Q){x,i,0};
q[++cnt]=(Q){y,i,1};
}
sort(q+1,q+cnt+1);
for(i=1;i<=cnt;++i){
if(q[i].v!=rv[tot]) rv[++tot]=q[i].v;
if(q[i].sd) le[q[i].id].r=tot;
else le[q[i].id].l=tot;
}
sort(le+1,le+n+1);
for(i=1;i<=n;++i){
j=0;
if(le[i].l>1) j=ask(1,1,tot,le[i].l-1);
if((!j) || a<=(ll)(rv[le[i].l]-rv[j])*b){
ans+=(a+(ll)b*(rv[le[i].r]-rv[le[i].l])%mod)%mod;
ans%=mod;
ad(1,1,tot,le[i].r,1);
}else{
ans+=(ll)b*(rv[le[i].r]-rv[j])%mod;
ans%=mod;
ad(1,1,tot,j,-1);ad(1,1,tot,le[i].r,1);
}
}
printf("%d",ans);
return 0;
}
E. Politics
最大費用最大流,設第一顆樹中的點為,第二顆樹中的點為。設為對號節點的總數限制。
從源點向連一條流量為(表示在子樹內且到路徑上沒有其它有限制的點),費用為的邊。
從向匯點連一條流量為,費用為的邊。
設表示深度最大的滿足在其子樹內的有限制結點(包括本身)。
從 向連一條流量為1,費用為的邊。
跑最大費用最大流即可。
#include<bits/stdc++.h>
const int inf=0x3f3f3f3f;
using namespace std;
typedef long long ll;
const int N=510,M=2e6+10;
int n,m,inn,ott,val[N],S,T,sum,rta,rtb,dmd[N<<1],col[N<<1];
int head[N<<1],to[M],nxt[M],w[M],cc[M],tot;
int dis[N<<1],pre[N<<1],bel[N<<1];bool inq[N<<1];
inline void fl(){printf("-1");exit(0);}
inline void lk(int u,int v,int flw,int cst)
{
to[++tot]=v;nxt[tot]=head[u];head[u]=tot;w[tot]=flw;cc[tot]=cst;
to[++tot]=u;nxt[tot]=head[v];head[v]=tot;w[tot]=0;cc[tot]=-cst;
}
int dfs(int x,int fa,int tpo)
{
int i,j,re=0;if(dmd[x]) tpo=x;
col[x]=tpo;
for(i=head[x];i;i=nxt[i]) if(to[i]!=fa)
re+=dfs(to[i],x,tpo);
if(dmd[x]){i=dmd[x];dmd[x]-=re;if(dmd[x]<0) fl();re=i;}
return re;
}
struct Pr{
int id,v;
bool operator<(const Pr&ky)const{
return v<ky.v;
}
}tp;
queue<int>que;
inline bool spfa()
{
memset(dis,0x3f,sizeof(dis));
int i,j,x;dis[S]=0;que.push(S);inq[S]=true;
for(;que.size();){
x=que.front();que.pop();
for(i=head[x];i;i=nxt[i]){
j=to[i];if((!w[i]) || dis[j]<=dis[x]+cc[i]) continue;
dis[j]=dis[x]+cc[i];pre[j]=x;bel[j]=i;
if(!inq[j]) que.push(j),inq[j]=true;
}
inq[x]=false;
}
return (dis[T]<inf);
}
int main(){
int i,j,x,y,z;
scanf("%d%d%d",&n,&rta,&rtb);S=(n<<1)+1;T=S+1;rtb+=n;
for(i=1;i<=n;++i) scanf("%d",&val[i]);
for(i=1;i<n;++i){scanf("%d%d",&x,&y);lk(x,y,0,0);}
for(i=1;i<n;++i){scanf("%d%d",&x,&y);lk(x+n,y+n,0,0);}
for(scanf("%d",&z);z;--z) {scanf("%d%d",&x,&y);dmd[x]=y;}
for(scanf("%d",&z);z;--z) {scanf("%d%d",&x,&y);dmd[x+n]=y;}
dfs(rta,0,rta);dfs(rtb,0,rtb);
memset(head,0,sizeof(head));tot=1;
for(i=1;i<=n;++i) if(dmd[i]) lk(S,i,dmd[i],0),inn+=dmd[i];
for(i=n+1;i<=n+n;++i) if(dmd[i]) lk(i,T,dmd[i],0),ott+=dmd[i];
if(inn!=ott) fl();
for(i=1;i<=n;++i)
lk(col[i],col[i+n],1,-val[i]);
z=inf;
for(;spfa();){
for(x=T;x!=S;x=pre[x]) z=min(z,w[bel[x]]);
for(x=T;x!=S;x=pre[x])
w[bel[x]]-=z,w[bel[x]^1]+=z;
sum-=z*dis[T];inn-=z;
}
if(inn!=0) fl();
printf("%d",sum);
return 0;
}
F. Lost Root
具體方法是先找到兩個在不同根節點兒子子樹中的葉節點,然後在它們之間的路徑上找根。
判斷一個點是否為葉結點:
隨機選另一個點,然後若所有其它點到的路徑都不經過,則為葉節點。複雜度為
找到一個葉結點:
隨機選到葉結點的概率,越大,概率越高。20次找不到的概率低到了。
找到另一個葉結點:隨機選一個點判斷在它與已知葉節點路徑上點數是否為。
找到根節點:直接排入相對位置即可。
懶得寫了,貼個標程
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
// #define endl "\n"
#define int long long
const int N=1e5+5;
int n, k, h, leaf1, leaf2;
int a[N];
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
vector<int> v, path;
map<tuple<int, int, int>, int> store;
int query(int a, int b, int c)
{
tuple<int, int, int> cur=make_tuple(a, b, c);
if(store.find(cur)!=store.end())
return (store[cur]);
cout<<"? "<<a<<" "<<b<<" "<<c<<endl;
string s;
cin>>s;
return (store[cur] = ((s=="Yes")));
}
int print(int x)
{
cerr<<x;
cout<<"! "<<x;
exit(0);
}
int findleaf()
{
while(true)
{
shuffle(a+1, a+n+1, rng);
int leaf=a[1];
int random=a[2];
bool check=1;
for(int i=3;i<=n;i++)
{
check&=(query(random, leaf, a[i])==0);
if(!check)
break;
}
if(check)
return leaf;
}
}
int findleaf2()
{
while(true)
{
int count=0;
shuffle(a+1, a+n+1, rng);
if(a[1]==leaf1)
continue;
int leaf=a[1];
bool check=1;
int cnt=0, reqd=2*(h-1) + 1;
v.clear();
for(int i=2;i<=n;i++)
{
if(a[i]==leaf1)
continue;
int current=query(leaf1, a[i], leaf);
cnt+=current;
if(current)
v.push_back(a[i]);
}
if(cnt==reqd)
return leaf;
}
}
void findroot()
{
path.push_back(leaf1);
path.push_back(v[0]);
path.push_back(leaf2);
for(int i=1;i<v.size();i++)
{
vector<int> newpath;
newpath.push_back(path[0]);
for(int j=1;j<path.size();j++)
{
if(query(path[j-1], v[i], path[j]))
{
newpath.push_back(v[i]);
for(int k=j;k<path.size();k++)
newpath.push_back(path[k]);
break;
}
else
newpath.push_back(path[j]);
}
path=newpath;
}
print(path[h]);
}
int32_t main()
{
cin>>n>>k;
if(n==1)
{
print(1);
return 0;
}
int cur=k;
int nodes=1;
h=0;
while(nodes+cur<=n)
{
nodes+=cur;
cur*=k;
h++;
}
for(int i=1;i<=n;i++)
a[i]=i;
leaf1=findleaf();
leaf2=findleaf2();
findroot();
return 0;
}
相關推薦
【Codeforces】Round #523 (Div. 2) A-F
A. Coins 貪心選儘量大的填 #include<bits/stdc++.h> using namespace std; typedef long long ll; int n,s,ans; int main(){ int i,j,mx
【Codeforces】 Round #524 (Div. 2) A-F
傳送門:CF524Div2 A. Petya and Origami 上取整 #include<bits/stdc++.h> using namespace std; typedef long long ll; int n,m,k;ll a,b,c; i
【codeforces】Round #522 (Div. 2) A+B+C+D
目錄 【A. Kitchen Utensils】 【B. Personalized Cup】 【C. Playing Piano】 【D. Barcelonian Distance】 【A. Kitchen Utensils】 題目連結:htt
【codeforces】Round #520 (Div. 2) A+B+C+D
目錄 A - A Prank B - Math C - Banh-mi D - Fun with Integers 【A - A Prank】 題目連結:http://codeforces.com/contest/1062/problem/A 【題意】 給你一串序
Codeforces Round #523 (Div. 2) A. Coins
A. Coins 題目連結:https://codeforc.es/contest/1061/problem/A 題意: 給出n和s,要在1-n中選數(可重複),問最少選多少數可以使其和為s。 題解: 貪心就行了。 程式碼如下: #include <c
Codeforces Round #516 (Div. 2) (A~F)
ring 2個 ica extra sdi ref code stdout extras 目錄 A.Make a triangle! B.Equations of Mathematical Magic C.Oh Those Palindromes D.Labyrinth(
【Codeforces Round #447 (Div. 2) A】QAQ
pro ont 題解 problem fde c語言 span bits endif 【鏈接】 我是鏈接,點我呀:) 【題意】 在這裏輸入題意 【題解】 C語言程序練習題 【代碼】 #include <bits/stdc++.h> using
Codeforces Round #197 (Div. 2) A. Helpful Maths【字符串/給一個連加計算式,只包含數字 1、2、3,要求重新排序,使得連加的數字從小到大】
asi man title problem beginning 排序 stand should cati A. Helpful Maths time limit per test 2 seconds memory limit per t
Codeforces Round #283 (Div. 2) A. Minimum Difficulty【一個數組定義困難值是兩個相鄰元素之間差的最大值。 給一個數組,可以去掉任意一個元素,問剩余數列的困難值的最小值是多少】
分析 options force minimum sta cif als 最小 技術分享 A. Minimum Difficulty time limit per test 2 seconds memory limit per test 256 mega
【Codeforces Round #457 (Div. 2) A】 Jamie and Alarm Snooze
als lar clu efi out .com bit source fin 【鏈接】 我是鏈接,點我呀:) 【題意】 在這裏輸入題意 【題解】 暴力往前走x分鐘就好。 直到出現7為止。 【代碼】 #include <bits/stdc++.h&
【Codeforces】 Educational Round 54 Div. 2 A-G
傳送門:cf1076 A. Minimizing the String 貪心刪去第一個字典序大於後一個位置的字母的位置。 #include<bits/stdc++.h> using namespace std; int n; char s[200005];
【codeforces】Codeforces Round #523 (Div. 2)
目錄 【B. Views Matter】貪心 【C. Multiplicity】dp+滾動陣列 【D. TV Shows】貪心 【B. Views Matter】 題目連結:https://codeforces.com/contest/1061/problem/B
【Codeforces Round #523(Div. 2)】TV Shows(貪心+map)
題目連結 D. TV Shows time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output The
【Codeforces Round #523(Div. 2)】Multiplicity(dp)
題目連結 C. Multiplicity time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output
【題解】codeforces1047A[Codeforces Round #511 (Div. 2)]A.Little C Loves 3 I 數學知識
題目連結 Description Little C loves number «3» very much. He loves all things about it. Now he has a positive integer n. He wants to sp
【Codeforces Round 332 (Div 2)A】【水題】A. Patrick and Shopping 遍歷三元環的最小成本
Today Patrick waits for a visit from his friend Spongebob. To prepare for the visit, Patrick needs to buy some goodies in two stores located near his hous
Codeforces Round #416 (Div. 2) A+B
src separate not sum redo swe tput output depend A. Vladik and Courtesy 2 seconds 256 megabytes At regular competition Vl
Codeforces Round #417 (Div. 2) A. Sagheer and Crossroads 模擬 枚舉
ces color 一次 name exit main cst space amp Codeforces Round #417 (Div. 2) A. Sagheer and Crossroads 模擬 枚舉 題意 一個紅綠燈 按逆時針方向一次給出各個路口的左轉,
Codeforces Round #422 (Div. 2) A. I'm bored with life 暴力
out line leave c++ ren round ... from cif A. I‘m bored with life Holidays have finished. Thanks to the help of t
Codeforces Round #306 (Div. 2) A
return code add stl ext scan java pac 一個 題意 給一個字符串(長度<=10^5)。問當中有沒有一個”BA”和一個”AB”呢?假設都有而且它們不反復(即ABA不算),輸出YES。否則輸出NO。 思路 一開