2017 icpc 瀋陽網路賽
阿新 • • 發佈:2018-11-22
題目:連結
B cable cable cable:
觀察得,答案為K*(M-K+1)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
ll M,K;
while(~scanf("%lld%lld",&M,&K))
printf("%lld\n",K*(M-K+1));
return 0;
}
D array array array:
若最長上升子序列的長度大於等於n-k,則是可以的,因為這裡要求的不是嚴格的遞增,
所以可以先將原陣列處理成沒有相同數字的陣列,然後處理就好了。
程式碼:
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+10; int n,k,dp[maxn],a[maxn]; vector<int>G[maxn]; bool check() { for(int i=0;i<maxn;i++) dp[i]=2e9; for(int i=0;i<n;i++) *lower_bound(dp,dp+n,a[i])=a[i]; int len=lower_bound(dp,dp+n,2e9)-dp; return n-len<=k; } int main() { int T;scanf("%d",&T); while(T--) { for(int i=0;i<maxn;i++) G[i].clear(); scanf("%d%d",&n,&k); for(int i=0;i<n;i++) { int x;scanf("%d",&x); G[x].push_back(i); } int tol=0; for(int i=1;i<maxn;i++) { int len=G[i].size(); for(int j=0;j<len;j++) { a[G[i][j]]=++tol; } } int ans=check(); tol=0; for(int i=1;i<maxn;i++) { int len=G[i].size(); for(int j=len-1;j>=0;j--) { a[G[i][j]]=++tol; } } ans|=check(); if(ans) printf("A is a magic array.\n"); else printf("A is not a magic array.\n"); } return 0; }
E number number number:
手推幾項發現是斐波那契數列的第2*(k+1)項,直接矩陣快速冪即可。
#include<bits/stdc++.h> using namespace std; #define ll long long const ll mod=998244353; struct node { ll t[2][2]; }a,b; node cheng(node &x,node &y) { node r; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { r.t[i][j]=0; for(int k=0;k<2;k++) (r.t[i][j]+=x.t[i][k]*y.t[k][j])%=mod; } } return r; } void pow1(int k) { while(k) { if(k&1) a=cheng(a,b); b=cheng(b,b); k/=2; } } int main() { int k; while(~scanf("%d",&k)) { a.t[0][0]=1,a.t[0][1]=0; a.t[1][0]=0,a.t[1][1]=0; b.t[0][0]=1,b.t[0][1]=1; b.t[1][0]=1,b.t[1][1]=0; pow1(2*(k+1)); printf("%lld\n",(a.t[0][0]-1+mod)%mod); } return 0; }
H transaction transaction transaction:
裸的樹分治:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct node
{
int to,cost,next;
}rode[maxn*2];
int val[maxn],n,tol,head[maxn];
int son[maxn],root,now_size;
bool vis[maxn];
int ans,cnt1,cnt2;
void add_edge(int a,int b,int c)
{
rode[tol].to=b;
rode[tol].cost=c;
rode[tol].next=head[a];
head[a]=tol++;
}
void get_root(int v,int fa,int SIZE)
{
son[v]=1;
int ma=0;
for(int i=head[v];i!=-1;i=rode[i].next)
{
node &e=rode[i];
if(e.to==fa||vis[e.to]) continue;
get_root(e.to,v,SIZE);
son[v]+=son[e.to];
ma=max(ma,son[e.to]);
}
ma=max(ma,SIZE-son[v]);
if(ma<now_size)
{
now_size=ma;
root=v;
}
}
void cal(int v,int fa,int par,int dist)
{
for(int i=head[v];i!=-1;i=rode[i].next)
{
node &e=rode[i];
if(e.to==fa||vis[e.to]) continue;
if(val[e.to]-val[par]-dist-e.cost>cnt1) cnt1=val[e.to]-val[par]-dist-e.cost;
if(val[par]-val[e.to]-dist-e.cost>cnt2) cnt2=val[par]-val[e.to]-dist-e.cost;
ans=max(ans,cnt1+cnt2);
cal(e.to,v,par,dist+e.cost);
}
}
void dfs(int v)
{
vis[v]=1;
cnt1=0,cnt2=0;
cal(v,0,v,0);
for(int i=head[v];i!=-1;i=rode[i].next)
{
node &e=rode[i];
if(vis[e.to]) continue;
get_root(root=e.to,v,now_size=son[e.to]);
dfs(root);
}
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
memset(vis,0,sizeof(vis));
memset(head,-1,sizeof(head));
tol=0;ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&val[i]);
for(int i=1;i<n;i++)
{
int x,y,z;scanf("%d%d%d",&x,&y,&z);
add_edge(x,y,z);add_edge(y,x,z);
}
get_root(root=1,0,now_size=n);
dfs(root);
printf("%d\n",ans);
}
return 0;
}
L card card card:
sum[i]為前i項值得字首和,若1~i之間所有的sum[i]都>=0,則滿足條件。
拓展即i~j中所有的sum[k]都滿足sum[k]>=sum[i-1],只要令j-i+1==n即可滿足題意。
程式碼:
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+10;
int deq[maxn],a[maxn],b[maxn],sum[maxn];
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) scanf("%d",&b[i]);
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]-b[i];
for(int i=1;i<=n;i++) sum[i+n]=sum[i+n-1]+a[i]-b[i];
int id=0;
for(int i=1;i<=2*n;i++)
{
while(sum[i]<sum[id]) id++;
if(i-id==n)
{
printf("%d\n",id);
break;
}
}
}
return 0;
}