# 6.22联考题解

A：

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

ll ans;
inline void read(ll &x)
{
char c; while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
x^=ans;
}
inline void up(int &a,const int &b){if(a<b)a=b;}
const int maxn = 210000;

int n,m,O;
int s[maxn];
int op[maxn][3],cnt;
struct Splay
{
int root;
int son[maxn][2],fa[maxn];
int siz[maxn];
ll sum[maxn][2];
int build(int l,int r)
{
int x=(l+r)>>1;
if(l==r) { siz[x]=1,sum[x][1]=s[x]; return x; }
if(l!=x) fa[son[x][0]=build(l,x-1)]=x;
if(x!=r) fa[son[x][1]=build(x+1,r)]=x;
pushup(x);
return x;
}
void pushup(int x)
{
int ls=siz[son[x][0]]&1;
sum[x][0]=sum[son[x][0]][0]+(ll)ls*s[x]+sum[son[x][1]][ls^1];
sum[x][1]=sum[son[x][0]][1]+(ll)(ls^1)*s[x]+sum[son[x][1]][ls];
siz[x]=siz[son[x][0]]+siz[son[x][1]]+1;
}
void rot(int x,int &k)
{
int y=fa[x],z=fa[y];
if(y!=k) son[z][son[z][1]==y]=x;
else k=x;
fa[x]=z;
int l=son[y][1]==x;
fa[son[y][l]=son[x][!l]]=y;
fa[son[x][!l]=y]=x;
pushup(y);
}
void splay(int x,int &k)
{
for(;x!=k;rot(x,k))
{
int y=fa[x],z=fa[y];
if(y!=k) rot(((son[y][1]==x)^(son[z][1]==y))?x:y,k);
}
pushup(x);
}
int go(int x,int t)
{
while(son[x][t]) x=son[x][t];
return x;
}
void Del(int x)
{
splay(x,root);
int y=go(son[x][0],1);
if(y)
{
splay(y,son[x][0]);
root=fa[son[y][1]=son[x][1]]=y;
}
else fa[root=son[x][1]]=0;
pushup(root);
}
void Ins(int x)
{
son[x][0]=son[x][1]=0;
sum[x][0]=0,sum[x][1]=s[x];
siz[x]=1;

for(int p=root,l;;p=son[p][l])
{
l=s[p]<s[x];
if(!son[p][l])
{
fa[son[p][l]=x]=p;
splay(x,root);
break;
}
}
}
ll cal() { return (siz[root]&1)?sum[root][1]-sum[root][0]:sum[root][0]-sum[root][1]; }
}tr;

int main()
{
freopen("round.in","r",stdin);
freopen("round.out","w",stdout);

scanf("%d%d%d",&n,&m,&O);
tr.root=tr.build(1,n);
for(int i=1;i<=m;i++)
{
int type; scanf("%d",&type);
if(type==1)
{
ll u,v; int w; read(u),read(v); scanf("%d",&w);
ans=0;
++cnt,op[cnt][0]=u,op[cnt][1]=v,op[cnt][2]=w;
tr.Del(u); if(u!=v) tr.Del(v);
s[u]+=w,s[v]+=w;
tr.Ins(u); if(u!=v) tr.Ins(v);
}
else
{
ll k; read(k);
ans=0;
int u=op[k][0],v=op[k][1],w=op[k][2];
tr.Del(u); if(u!=v) tr.Del(v);
s[u]-=w,s[v]-=w;
tr.Ins(u); if(u!=v) tr.Ins(v);
}
ans=tr.cal()>>1;
printf("%lld\n",ans);
ans*=O;
}

return 0;
}


B：

$T$$T$看作障碍点，设$f\left[i\right]$$f[i]$表示$S$$S$到第$i$$i$个障碍点，中途不经过其他障碍点的方案数，转移的时候容斥一下，总方案数减不合法的，不合法的通过枚举遇到的第一个障碍点计算$f\left[i\right]=ways\left(S,i\right)-\sum f\left[j\right]ways\left(j,i\right)$$f[i]=ways(S,i)-\sum f[j]ways(j,i)$

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxc = 210000;
const int maxn = 405;
const int mod  = 998244353;
inline void add(int &a,const int &b){a+=b;if(a>=mod)a-=mod;}
inline void dec(int &a,const int &b){a-=b;if(a<0)a+=mod;}

int pw(int x,int k)
{
int re=1;
for(;k;k>>=1,x=(ll)x*x%mod) if(k&1)
re=(ll)re*x%mod;
return re;
}
int inv(int x){ return pw(x,mod-2); }
int s[maxc],invs[maxc];
void pre()
{
s[0]=1; for(int i=1;i<maxc;i++) s[i]=(ll)s[i-1]*i%mod;
invs[maxc-1]=inv(s[maxc-1]);
for(int i=maxc-2;i>=0;i--) invs[i]=(ll)invs[i+1]*(i+1)%mod;
}
int C(int i,int j){ return i>=j?(ll)s[i]*invs[j]%mod*invs[i-j]%mod:0; }

int n,m,p,q;
struct point
{
int x,y;
int cal(point z)
{
if(z.x<x||z.y<y) return 0;
return C(z.x-x+z.y-y,z.x-x);
}
}st[maxn],ed[maxn],pi[maxn];
inline bool cmp(const point x,const point y){ return x.x==y.x?x.y<y.y:x.x<y.x; }

namespace Gauss
{
int n;
int a[maxn][maxn];
int Solve()
{
for(int i=1;i<n;i++)
{
if(!a[i][i])
{
int k=0;
for(int j=i+1;j<=n;j++) if(a[j][i]) { k=j;break; }
if(k)
{
for(int j=i;j<=n;j++) swap(a[i][j],a[k][j]);
}
else continue;
}
int ii=inv(a[i][i]);
for(int j=1;j<=n;j++) if(a[j][i]&&j!=i)
{
int k=(ll)ii*a[j][i]%mod;
for(int l=i;l<=n;l++) dec(a[j][l],(ll)a[i][l]*k%mod);
}
}
int ans=1;
for(int i=1;i<=n;i++) ans=(ll)ans*a[i][i]%mod;
return ans;
}
}

int f[maxn];

int main()
{
freopen("canal.in","r",stdin);
freopen("canal.out","w",stdout);

pre();

scanf("%d%d%d%d",&n,&m,&p,&q);
for(int i=1;i<=p;i++) st[i].x=0,scanf("%d",&st[i].y);
for(int i=1;i<=p;i++) ed[i].x=n,scanf("%d",&ed[i].y);
for(int i=1;i<=q;i++) scanf("%d%d",&pi[i].x,&pi[i].y);

sort(st+1,st+p+1,cmp);
sort(ed+1,ed+p+1,cmp);
sort(pi+1,pi+q+1,cmp);

Gauss::n=p;
for(int i=1;i<=p;i++)
{
for(int j=1;j<=q;j++)
{
f[j]=st[i].cal(pi[j]);
for(int k=1;k<j;k++) dec(f[j],(ll)f[k]*pi[k].cal(pi[j])%mod);
}
for(int j=1;j<=p;j++)
{
int &temp=Gauss::a[i][j];
temp=st[i].cal(ed[j]);
for(int k=1;k<=q;k++) dec(temp,(ll)f[k]*pi[k].cal(ed[j])%mod);
}
}
printf("%d\n",Gauss::Solve());

return 0;
}


C：
Simpson积分能拿50pt

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120