ゲームリンク:https://www.cometoj.com/contest/74
T1
まず、操作はどのような場合には全体の配列を変化させないため、2つの配列が同一ではないから直接判断し、
次に、定義の動作は知ることは困難ではない:(\ \ {B_i \} \)と各非ゼロエントリの対応する(\ {a_iを\} \ \ ) 部と、各セグメントの数は、交差しません、これらのセグメントのすべてが一緒に正確にどのような元のシーケンスを置きます。現在のシーケンスがカバーされている維持我々はそう(\ {a_iを\} \ \ ) すべてのゼロ以外を掃引するために、右のポイントを(\ {b_i \} \ \ ) と右とき暴力を拡大
統計回答:それぞれの期間は、\(\ {a_iを\} \ ) に\(b_iは\)ただ一つの操作が必要ですが、あなたが持って起こる場合は、\(a_iを= b_i \)で動作するために必要とされていません。なお、この時点で\(a_iを= 0 \)判決の効果は、することができます\(0 \)が来るように考慮され、それが判断された\(I \)このセクションでは範囲内とすることができるかどうか
#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
const int N=10000;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define eps 1e-8
int n,a[100100],b[100100];
int read()
{
int x=0,f=1;char ch=getchar();
while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
return x*f;
}
int main()
{
//freopen("begin2.in","r",stdin);
int T=read();
while (T--)
{
n=read();
ll sum1=0,sum2=0;
rep(i,1,n) {a[i]=read();sum1+=a[i];}
rep(i,1,n) {b[i]=read();sum2+=b[i];}
if (sum1!=sum2) {puts("-1");continue;}
//cout << sum1 << endl;
int r=1,ok=1,ans=0;
rep(i,1,n)
{
if (!b[i]) continue;
ll sum=0;ans++;
int l=r;
while ((sum<b[i]) && (r<=n)) {sum+=a[r];r++;}
if (sum!=b[i]) {ok=0;break;}
if ((i>=l) && (i<=r-1) && (a[i]==b[i])) ans--;
//cout << i << " "<< l << " " << r-1 << endl;
}
if (ok) printf("%d\n",ans);
else puts("-1");
}
return 0;
}
T2
本明細書に記載する「最短経路」は、最小エッジウェイトのパスの最大値を満たさなければなりません
用((S、T)\ \ ) パスの右側に最小エッジの最大値、我々はMSTによって見つけることができ、次いで、再帰
各再帰的には、同じことをやっていることをしていることがわかった((S、T)を\ \ ) 最短経路はそのです\(MST \)上のパス
#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
const int N=10000;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define eps 1e-8
struct node{int to,nxt,cost;}sq[600600];
int all=0,head[300300];
int n,m,q,fa[300300][20],f[300300],dep[300300];
ll dis[300300],bin[300300];
int read()
{
int x=0,f=1;char ch=getchar();
while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
return x*f;
}
int find(int x)
{
if (f[x]==x) return x;
f[x]=find(f[x]);
return f[x];
}
void add(int u,int v,int w)
{
all++;sq[all].to=v;sq[all].nxt=head[u];sq[all].cost=bin[w];head[u]=all;
}
void dfs(int u,int fu)
{
dep[u]=dep[fu]+1;fa[u][0]=fu;
rep(i,1,19) fa[u][i]=fa[fa[u][i-1]][i-1];
for (int i=head[u];i;i=sq[i].nxt)
{
int v=sq[i].to;
if (v==fu) continue;
dis[v]=(dis[u]+sq[i].cost)%maxd;
dfs(v,u);
}
}
int LCA(int u,int v)
{
if (dep[u]<dep[v]) swap(u,v);
int tmp=dep[u]-dep[v];
per(i,19,0)
if ((tmp>>i)&1) u=fa[u][i];
if (u==v) return u;
per(i,19,0)
if (fa[u][i]!=fa[v][i])
{
u=fa[u][i];v=fa[v][i];
}
return fa[u][0];
}
int main()
{
n=read();m=read();
rep(i,1,n) f[i]=i;
bin[0]=1;
rep(i,1,m) bin[i]=bin[i-1]*2%maxd;
rep(i,1,m)
{
int x=read(),y=read();
int fx=find(x),fy=find(y);
if (fx!=fy)
{
add(x,y,i);add(y,x,i);
f[fx]=fy;
}
}
dfs(1,0);
//rep(i,1,n) cout << dep[i] << " ";cout << endl;
int q=read();
while (q--)
{
int u=read(),v=read(),w=LCA(u,v);
ll ans=dis[u]+dis[v]-dis[w]*2;
ans=(ans%maxd+maxd)%maxd;
printf("%lld\n",ans);
}
return 0;
}
T3
最初の決定(\ \ {a_iを\} \ ) すべての人が攻撃と仮定すると、回答に貢献誰もが、係数が乗算されるため、\(\ FRAC {1} { 2 ^ n}は、\ FRAC {1} 2-N- ^ {{}}。1、\ cdots、\ FRAC。1} {2} {\)ので、元の配列が注文最適昇順であることを、
:次は、所望の式DPに困難ではない列挙し\(。。F_iと= \ FRAC 1} {2} {F_ {I} -1- + \ FRAC F_ {} + {I-a_iを1} {2} \) 、仕上げ与える\(F_iと= \ {} {} 4-F_ 1} + {I \ FRAC 1は{{}}。4 a_iをを\ 3 FRAC) 、明らかに直接的に行われます。
各検討\(a_iを\)の\(F_n \)の寄与を、のように書くことができる(f_n = \ sum_ {iは\ = 1} ^ N \ FRAC {1} {4}・(\ FRAC {3} {4} )^ {}ニッケルa_iを\) 、そう)a_iを\(\解答への影響とそれが唯一のランキングについてです、重みツリーラインのメンテナンスと、メンテナンス\(F \)とランキング。以来\(a_iを\)大きなダイナミックその後、処方箋(ただし、定数大)を書きました
#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
const int N=1e9;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define eps 1e-8
int rt=0,n,m,q,tot=0,a[100100],siz[3903000],lson[3903000],rson[3903000];
ll seg[3900300],tag[3903000],inv34,inv43,f[100100];
int read()
{
int x=0,f=1;char ch=getchar();
while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
return x*f;
}
int add(int x,int y)
{
int ans=x+y;
if (ans>=maxd) ans-=maxd;
return ans;
}
ll qpow(ll x,int y)
{
ll ans=1;
while (y)
{
if (y&1) ans=ans*x%maxd;
x=x*x%maxd;y>>=1;
}
return ans;
}
void pushdown(int id)
{
if (tag[id]!=1)
{
if (lson[id])
{
seg[lson[id]]=seg[lson[id]]*tag[id]%maxd;
tag[lson[id]]=tag[lson[id]]*tag[id]%maxd;
}
if (rson[id])
{
seg[rson[id]]=seg[rson[id]]*tag[id]%maxd;
tag[rson[id]]=tag[rson[id]]*tag[id]%maxd;
}
tag[id]=1;
}
}
void modify(int &id,int l,int r,int pos,ll val,int v)
{
if (!id) {id=(++tot);tag[id]=1;}
pushdown(id);
seg[id]=(seg[id]+val+maxd)%maxd;siz[id]+=v;
if (l==r) return;
int mid=(l+r)>>1;
if (pos<=mid) modify(lson[id],l,mid,pos,val,v);
else modify(rson[id],mid+1,r,pos,val,v);
}
void modifyr(int &id,int l,int r,int ql,int qr,ll val)
{
if (!id) {id=(++tot);tag[id]=1;}
if ((l>qr) || (r<ql)) return;
pushdown(id);
if ((l>=ql) && (r<=qr))
{
seg[id]=seg[id]*val%maxd;
tag[id]=tag[id]*val%maxd;
return;
}
int mid=(l+r)>>1;
if (ql<=mid) modifyr(lson[id],l,mid,ql,qr,val);
if (qr>mid) modifyr(rson[id],mid+1,r,ql,qr,val);
seg[id]=(seg[lson[id]]+seg[rson[id]])%maxd;
}
int query(int id,int l,int r,int ql,int qr)
{
if (!id) return 0;
if ((l>qr) || (r<ql)) return 0;
if ((l>=ql) && (r<=qr)) return siz[id];
int mid=(l+r)>>1;int ans=0;
if (ql<=mid) ans+=query(lson[id],l,mid,ql,qr);
if (qr>mid) ans+=query(rson[id],mid+1,r,ql,qr);
return ans;
}
void add(int x)
{
int k=query(rt,0,N,x,N)+1;
modify(rt,0,N,x,f[k]*x%maxd,1);
if (x) modifyr(rt,0,N,0,x-1,inv34);
}
void del(int x)
{
int k=query(rt,0,N,x,N);
modify(rt,0,N,x,-f[k]*x%maxd,-1);
if (x) modifyr(rt,0,N,0,x-1,inv43);
}
void init()
{
inv34=qpow(4,maxd-2)*3%maxd;
inv43=qpow(3,maxd-2)*4%maxd;
f[1]=qpow(4,maxd-2);
rep(i,2,n) f[i]=f[i-1]*inv34%maxd;
}
int main()
{
//freopen("relation3.in","r",stdin);
//freopen("a.out","w",stdout);
n=read();init();
rep(i,1,n) {a[i]=read();add(a[i]);}
printf("%lld\n",seg[rt]);
q=read();
while (q--)
{
int pos=read(),val=read();
del(a[pos]);a[pos]=val;add(a[pos]);
printf("%lld\n",seg[rt]);
}
return 0;
}