[T1 序列计数]
题解:
\(DP\)可做,\(F[i][j]\),表示第\(i\)个数组成的好序列左边差\(j\)个数时的方案数;
\(code\):
#include<stdio.h>
#include<algorithm>
#include<ctype.h>
#define mod 998244353
using namespace std;
inline int add(int a,int b){return a+b<mod?a+b:a+b-mod;}
int n,a[5005],f[5005][5005];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
if(a[1]>0&&a[1]<=n-1) f[1][a[1]]=1;
for(int i=2;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
f[i][j]=f[i-1][j];
if(j) f[i][j-1]=add(f[i][j-1],f[i-1][j]);
}
if(a[i]>0&&a[i]<=n-1) f[i][a[i]]=add(f[i][a[i]],f[i-1][0]+1);
}
printf("%d",f[n][0]);
}
[T2 僵尸大战植物引发的惨♂案 ]
题解:
预处理出对于一个点\(S\),起点到他的距离,他一路坐到站底时的最优时间(坐到站底\(T\)的时间\(+\)坐到终点的时间),把这个当成边丢进\(vector\),二分一个答案验证;
\(code:\)
#include<stdio.h>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
const ll N=25001,inf=1e18;
struct www{
ll to,len;
www(ll to=0,ll len=0):
to(to),len(len){}
bool operator<(const www x)const{
return len>x.len;
}
};
priority_queue<www>q;
vector<www>g[N],qwq[N];
ll n,m,s,t,lim,w[N],sum[N],sub[N],dis[N];
void dijkstra(ll s,bool f){
for(ll i=0;i<n;i++)dis[i]=inf;
q.push(www(s,0));dis[s]=0;
while(!q.empty()){
ll x=q.top().to,_dis=q.top().len;
q.pop();if(dis[x]!=_dis)continue;
for(ll i=g[x].size()-1;i>=0;i--){
ll y=g[x][i].to,len=g[x][i].len+_dis;
bool ok=f|(len+qwq[x][i].len<=lim);
if(dis[y]>len&&ok)dis[y]=len,q.push(www(y,len));
}
}
}
int main(){
scanf("%lld%lld%lld%lld",&n,&m,&s,&t);
for(ll i=1;i<=m;i++){
scanf("%lld",&sub[0]);
for(ll j=1;j<=sub[0];j++)scanf("%lld",&sub[j]);
for(ll j=1;j<sub[0];j++){
scanf("%lld",&w[j]);
sum[j]=sum[j-1]+w[j];
}
for(ll j=1;j<sub[0];j++){
g[sub[j]].push_back(www(sub[j+1],w[j]));
g[sub[j+1]].push_back(www(sub[j],w[j]));
qwq[sub[j]].push_back(www(sub[sub[0]],sum[sub[0]-1]-sum[j]));
qwq[sub[j+1]].push_back(www(sub[1],sum[j-1]));
}
}
dijkstra(t,1);
for(ll i=0;i<n;i++)
for(ll j=qwq[i].size()-1;j>=0;j--)
qwq[i][j].len+=dis[qwq[i][j].to];
ll l=0,r=inf;
while(l<=r){
lim=l+r>>1;
dijkstra(s,0);
if(dis[t]==inf)l=lim+1;
else r=lim-1;
}
printf("%lld",l);
}
[T3 深夜放毒]
题解:
说实话想到很简单,写起来确实恶心,典型的树套树,横向维护一颗线段树,纵向维护一颗线段树,不想写=_=,于是放上出题人自己的代码
\(code:\)
#include <stdio.h>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
int k,lim;
const int QAQ=20000000;
int ls[QAQ],rs[QAQ];
ll sum[QAQ],lazy[QAQ];
int tot=1;
void mdf(int now,int l,int r,int x,int y,ll v)
{
if(x<=l&&y>=r)
{
sum[now]+=(r-l+1)*v;
lazy[now]+=v;
return;
}
int mid=l+r >>1;
if(lazy[now])
{
ll v=lazy[now];
lazy[now]=0;
if(!ls[now])ls[now]=++tot;
if(!rs[now])rs[now]=++tot;
sum[ls[now]]+=(mid-l+1)*v;
sum[rs[now]]+=(r-mid)*v;
lazy[ls[now]]+=v;
lazy[rs[now]]+=v;
}
if(x<=mid)
{
if(!ls[now])ls[now]=++tot;
mdf(ls[now],l,mid,x,y,v);
}
if(y>mid)
{
if(!rs[now])rs[now]=++tot;
mdf(rs[now],mid+1,r,x,y,v);
}
sum[now]=sum[ls[now]]+sum[rs[now]];
}
ll get(int now,int l,int r,int x,int y)
{
if(!now)return 0;
if(x<=l&&y>=r)return sum[now];
int mid=l+r >>1;
ll tmp=0;
if(lazy[now])
{
ll v=lazy[now];
lazy[now]=0;
if(!ls[now])ls[now]=++tot;
if(!rs[now])rs[now]=++tot;
sum[ls[now]]+=(mid-l+1)*v;
sum[rs[now]]+=(r-mid)*v;
lazy[ls[now]]+=v;
lazy[rs[now]]+=v;
}
if(x<=mid)tmp+=get(ls[now],l,mid,x,y);
if(y>mid)tmp+=get(rs[now],mid+1,r,x,y);
return tmp;
}
int lb(int x)
{return x&(-x);}
void MODIFY(int xxx,int x,int y,ll v)
{while(xxx<=k)mdf(xxx,0,lim-1,x,y,v),xxx+=lb(xxx);}
ll QUERY(int xxxx,int x)
{ll t=0;while(xxxx)t+=get(xxxx,0,lim-1,x,x),xxxx-=lb(xxxx);return t;}
char buf[1<<20],*p1,*p2;
#define GC (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?0:*p1++)
inline int R()
{
int p=0;
char o=GC;
while(o<48||o>57)o=GC;
while(o>=48&&o<=57)
{
p=(p<<1)+(p<<3)+o-48;
o=GC;
}
return p;
}
void FangDu()
{
int x=R(),h=R();
ll v=R();
mdf(k+1,0,lim-1,x/k-h,x/k,v);
mdf(k+1,0,lim-1,(x+1)/k,(x+1)/k+h,-v);
MODIFY(x%k+1,x/k-h,x/k,v);
MODIFY((x+1)%k+1,(x+1)/k,(x+1)/k+h,-v);
}
void XunWen()
{
int x=R();
int alk=(x+1)/k-1;
ll ans=0;
if(alk>=0)
ans+=get(k+1,0,lim-1,0,alk);
if((x+1)%k!=0)
ans+=QUERY(x%k+1,x/k);
printf("%lld\n",ans);
}
//Please Do Not Diss Me !!!!
int main()
{
k=R(),lim=R();
int i,m=R();
tot=k+1;
while(m--)
{
i=R();
if(i==1)FangDu();
else XunWen();
}
return 0;
}