来自aakennes的新年祝福
来自aakennes的新年祝福
组题人: @aakennes
P888. 字符串会上树
-
基础字符串。
点击查看代码
string s,t="",w=""; map<string,string>f; int main() { // #define Isaac #ifdef Isaac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif int n,q,i; cin>>n>>q>>s; for(i=0;i<=n-1;i++) { if(s[i]=='&') { f[t]=w; t=""; } else if(s[i]=='=') w=""; else if('0'<=s[i]&&s[i]<='9') w+=s[i]; else t+=s[i]; } if(t!="") f[t]=w; for(i=1;i<=q;i++) { cin>>s; if(f.find(s)==f.end()) cout<<"Does not exist."<<endl; else cout<<f[s]<<endl; } return 0; }
P889. 挖宝石
-
背包循环移位转移。
点击查看代码
bool f[2][3010]; int main() { // #define Isaac #ifdef Isaac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif ll n,k,x,i,j; cin>>n>>k; for(i=1;i<=n;i++) { cin>>x; x%=k; for(j=0;j<=x-1;j++) f[i&1][j]=f[(i-1)&1][j]|f[(i-1)&1][(j-x+k)%k]; for(j=x;j<=k-1;j++) f[i&1][j]=f[(i-1)&1][j]|f[(i-1)&1][j-x]; f[i&1][x]=1; if(f[i&1][0]==1) { cout<<"Yes"<<endl; return 0; } } cout<<"No"<<endl; return 0; }
P890. 电梯系统
-
手摸样例,得到一种构造方式形如
1->2->3->4->5->6->7 1---->3---->5---->7 1------->4---->6 1---------->5 1------------->6 1---------------->7 2---->4------->7 2------->5 2---------->6 2------------->7 3------>6 3------>7
-
可知
即为所求。点击查看代码
int main() { // #define Isaac #ifdef Isaac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif ll n,ans=0,i; cin>>n; for(i=1;i<=n;i++) { if(2*i-1<=n) ans+=n-(2*i-1); } cout<<ans<<endl; return 0; }
P891. 打游戏
-
和求树的直径一样做即可。
点击查看代码
struct node { ll nxt,to,w; }e[200010]; ll head[100010],a[100010],f[100010],g[100010],len,cnt=0; void add(ll u,ll v,ll w) { cnt++; e[cnt].nxt=head[u]; e[cnt].to=v; e[cnt].w=w; head[u]=cnt; } void dfs(ll x,ll fa) { for(ll i=head[x];i!=0;i=e[i].nxt) { if(e[i].to!=fa) { dfs(e[i].to,x); if(f[e[i].to]-e[i].w>f[x]) { g[x]=f[x]; f[x]=f[e[i].to]-e[i].w; } else { g[x]=max(g[x],f[e[i].to]-e[i].w); } } } f[x]+=a[x]; len=max(len,f[x]+g[x]); } int main() { // #define Isaac #ifdef Isaac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif ll n,u,v,w,i; cin>>n; for(i=1;i<=n;i++) cin>>a[i]; for(i=1;i<=n-1;i++) { cin>>u>>v>>w; add(u,v,w); add(v,u,w); } dfs(1,0); cout<<len<<endl; return 0; }
P892. 魔法水晶
-
考虑建出最短路
后补全成原图并计数。点击查看代码
const ll p=998244353; ll a[200010],cnt[200010]; ll qpow(ll a,ll b,ll p) { ll ans=1; while(b) { if(b&1) ans=ans*a%p; b>>=1; a=a*a%p; } return ans; } int main() { // #define Isaac #ifdef Isaac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif ll n,ans=1,i; cin>>n; for(i=1;i<=n;i++) { cin>>a[i]; cnt[a[i]]++; } for(i=1;i<=n-1&&cnt[i]!=0;i++) ans=ans*qpow((qpow(2,cnt[i-1],p)-1+p)%p,cnt[i],p)%p*qpow(2,cnt[i]*(cnt[i]-1)/2,p)%p; for(;i<=n-1;i++) if(cnt[i]!=0) ans=0; cout<<ans<<endl; return 0; }
P893. 随机数序列
-
根据左右移位时不变的位置顺次求出其他位置。
点击查看代码
uint a[200010],t[50]; pair<uint,uint>c[200010]; uint random(uint& seed) { seed ^= (seed << 16); seed ^= (seed >> 5); seed ^= (seed << 1); return seed; } uint rev(uint x) { for(int i=31;i>=0;i--) t[i]=(x>>i)&1; for(int i=1;i<=31;i++) t[i]^=t[i-1]; for(int i=26;i>=0;i--) t[i]^=t[i+5]; for(int i=16;i<=31;i++) t[i]^=t[i-16]; x=0; for(int i=31;i>=0;i--) x=(x<<1)|t[i]; return x; } int main() { // #define Isaac #ifdef Isaac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif int n,i; uint seed; cin>>n; for(i=1;i<=n;i++) cin>>c[i].first>>c[i].second; sort(c+1,c+1+n); seed=a[c[1].first]=c[1].second; for(i=c[1].first+1;i<=200000;i++) a[i]=random(seed); for(i=2;i<=n;i++) { if(a[c[i].first]!=c[i].second) { cout<<"no"<<endl; return 0; } } seed=c[1].second; for(i=1;i<=c[1].first;i++) seed=rev(seed); cout<<seed<<endl; return 0; }
P894. 线段树改造
-
观察到循环移位
,询问时的 提出来最后再加。点击查看代码
int a[200010]; struct SMT { struct SegmentTree { int len,sum,lazy; }tree[800010]; #define lson(rt) (rt<<1) #define rson(rt) (rt<<1|1) void pushup(int rt) { tree[rt].sum=(tree[lson(rt)].sum+tree[rson(rt)].sum)%4; } void build(int rt,int l,int r) { tree[rt].len=r-l+1; if(l==r) { tree[rt].sum=a[l]; return; } int mid=(l+r)/2; build(lson(rt),l,mid); build(rson(rt),mid+1,r); pushup(rt); } void pushlazy(int rt,int lazy) { tree[rt].lazy=(tree[rt].lazy+lazy)%4; tree[rt].sum=(tree[rt].sum+lazy*tree[rt].len)%4; } void pushdown(int rt) { pushlazy(lson(rt),tree[rt].lazy); pushlazy(rson(rt),tree[rt].lazy); tree[rt].lazy=0; } void update(int rt,int l,int r,int x,int y,int val) { if(x<=l&&r<=y) { pushlazy(rt,val); return; } pushdown(rt); int mid=(l+r)/2; if(x<=mid) update(lson(rt),l,mid,x,y,val); if(y>mid) update(rson(rt),mid+1,r,x,y,val); pushup(rt); } int query(int rt,int l,int r,int x,int y) { if(x<=l&&r<=y) return tree[rt].sum; pushdown(rt); int mid=(l+r)/2; if(y<=mid) return query(lson(rt),l,mid,x,y); if(x>mid) return query(rson(rt),mid+1,r,x,y); return (query(lson(rt),l,mid,x,y)+query(rson(rt),mid+1,r,x,y))%4; } }T; int main() { // #define Isaac #ifdef Isaac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif int n,m,pd,l,r,x,i; cin>>n>>m; for(i=1;i<=n;i++) cin>>a[i]; T.build(1,1,n); for(i=1;i<=m;i++) { cin>>pd>>l>>r; if(pd==1) { cin>>x; T.update(1,1,n,l,r,x+1); } else { cout<<(r-l+T.query(1,1,n,l,r))%4<<endl; } } return 0; }
P895. 赌博
-
题目要求找到
的最小正整数解,观察到有用的 且 ,枚举即可。点击查看代码
int main() { // #define Isaac #ifdef Isaac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif ll t,n,x,p,r,flag,i,j; cin>>t; for(j=1;j<=t;j++) { cin>>n>>x>>p; flag=0; for(i=1;i<=p&&i<=n-1;i++) { if((i*(i+1)/2%n+x)%n==0) { flag=1; cout<<"Yes"<<endl; break; } } if(flag==0) cout<<"No"<<endl; } return 0; }
P896. 魔法水晶2
P897. 对战
-
稍微卡卡常。
点击查看代码
const int p=998244353; int C[7010][7010],f[2][2][7010][20]; int qadd(int a,int b) { return a+b>=p?a+b-p:a+b; } int main() { // #define Isaac #ifdef Isaac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif int n,m,tmp,tmp1,tmp2,i,j,k; cin>>n>>m; if(1.0*m>log2(n)+5.0) { cout<<0<<endl; } else { C[0][0]=C[1][0]=C[1][1]=1; for(i=2;i<=n;i++) { C[i][0]=1; for(j=1;j<=i;j++) { C[i][j]=(C[i-1][j-1]+C[i-1][j])%p; } } for(i=0;i<=m;i++) { f[0][0][0][i]=f[0][1][0][i]=f[1][0][0][i]=f[1][1][0][i]=1; } for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { for(k=1;k<=i;k++) { tmp=C[i-1][k-1]; f[0][0][i][j]=qadd(f[0][0][i][j],(1ll*f[0][1][k-1][j]*f[1][0][i-k][j]%p)*tmp%p); f[1][0][i][j]=qadd(f[1][0][i][j],(1ll*f[1][1][k-1][j-1]*f[1][0][i-k][j]%p)*tmp%p); f[0][1][i][j]=qadd(f[0][1][i][j],(1ll*f[0][1][k-1][j]*f[1][1][i-k][j-1]%p)*tmp%p); tmp1=(f[1][1][k-1][j]-f[1][1][k-1][j-1]+p)%p; tmp2=(f[1][1][i-k][j]-f[1][1][i-k][j-1]+p)%p; f[1][1][i][j]=qadd(f[1][1][i][j],((1ll*f[1][1][k-1][j]*f[1][1][i-k][j]%p-1ll*tmp1*tmp2%p+p)%p)*tmp%p); } } } cout<<(f[0][0][n][m]-f[0][0][n][m-1]+p)%p<<endl; } return 0; }
P898. 交通网络
P899. 疯狂的矩阵
P900. 超级计算机
-
swap
被调用次数等价于全局逆序对数。 -
弱化版中树套树或分块的做法不适用于本题。
-
考虑将连续的一段缩成一个点进行处理,离散化维护。
点击查看代码
const ll p=998244353; ll d[200010],x[200010],y[200010]; map<ll,ll>a; map<ll,ll>::iterator it; struct BIT { ll c[200010]; ll lowbit(ll x) { return (x&(-x)); } void clear() { memset(c,0,sizeof(c)); } void add(ll n,ll x,ll val) { for(ll i=x;i<=n;i+=lowbit(i)) c[i]+=val; } ll getsum(ll x) { ll ans=0; for(ll i=x;i>=1;i-=lowbit(i)) ans+=c[i]; return ans; } ll query(ll l,ll r) { return l<=r?getsum(r)-getsum(l-1):0; } }T; int main() { // #define Isaac #ifdef Isaac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif ll n,m,l,r,ans=0,i; cin>>n>>m; for(i=1;i<=m;i++) { cin>>l>>r; if(l>r) swap(l,r); d[0]++; d[d[0]]=l; d[0]++; d[d[0]]=r; if(a.find(l)==a.end()) a[l]=l; if(a.find(r)==a.end()) a[r]=r; swap(a[l],a[r]); } sort(d+1,d+1+d[0]); d[0]=unique(d+1,d+1+d[0])-(d+1); m=0; for(it=a.begin();it!=a.end();it++) { m++; x[m]=lower_bound(d+1,d+1+d[0],it->first)-d; y[m]=lower_bound(d+1,d+1+d[0],it->second)-d; ans=(ans+max(0ll,abs(it->second-it->first)-1))%p; } for(i=1;i<=m;i++) { ans=(ans-T.query(min(x[i],y[i])+1,max(y[i],x[i])-1)+p)%p; T.add(d[0],y[i],1); } T.clear(); for(i=m;i>=1;i--) { ans=(ans-T.query(min(x[i],y[i])+1,max(y[i],x[i])-1)+T.getsum(y[i]-1)+p)%p; T.add(d[0],y[i],1); } cout<<ans<<endl; return 0; }
P901. 线段树改造2
-
既然已经限制了
具有结合律,线段树直接维护即可。 -
难点在于中缀表达式求值,建议先去写 luogu P10473 表达式计算4 。
点击查看代码
const int p=998244353; int a[200010],len; char s[60]; stack<int>s1; stack<char>s2; int val(char x) { if(x=='(') return 0; if(x=='+'||x=='-') return 1; if(x=='*') return 2; return -1; } void work() { int a=s1.top(); s1.pop(); int b=s1.top(); s1.pop(); char c=s2.top(); s2.pop(); if(c=='+') s1.push((b+a)%p); if(c=='-') s1.push((b-a+p)%p); if(c=='*') s1.push(1ll*b*a%p); } int ask(int x,int y) { int tmp=0,flag=0; for(int i=1;i<=len;i++) { if(('0'<=s[i]&&s[i]<='9')||s[i]=='a'||s[i]=='b') { if('0'<=s[i]&&s[i]<='9') tmp=(tmp*10%p+s[i]-'0')%p; else tmp=(s[i]=='a')?x:y; flag=1; if(i==len) s1.push(tmp); } else { if(flag==1) { s1.push(tmp); tmp=flag=0; } if(s[i]=='(') s2.push(s[i]); else if(s[i]==')') { while(s2.top()!='(') work(); s2.pop(); } else { while(s2.empty()==0&&val(s2.top())>=val(s[i])) work(); s2.push(s[i]); } } if(i==len) while(s2.empty()==0) work(); } return s1.top(); } struct SMT { struct SegmentTree { int sum; }tree[800010]; #define lson(rt) (rt<<1) #define rson(rt) (rt<<1|1) void pushup(int rt) { tree[rt].sum=ask(tree[lson(rt)].sum,tree[rson(rt)].sum); } void build(int rt,int l,int r) { if(l==r) { tree[rt].sum=a[l]; return; } int mid=(l+r)/2; build(lson(rt),l,mid); build(rson(rt),mid+1,r); pushup(rt); } void update(int rt,int l,int r,int pos,int val) { if(l==r) { tree[rt].sum=ask(tree[rt].sum,val); return; } int mid=(l+r)/2; if(pos<=mid) update(lson(rt),l,mid,pos,val); else update(rson(rt),mid+1,r,pos,val); pushup(rt); } int query(int rt,int l,int r,int x,int y) { if(x<=l&&r<=y) return tree[rt].sum; int mid=(l+r)/2; if(y<=mid) return query(lson(rt),l,mid,x,y); if(x>mid) return query(rson(rt),mid+1,r,x,y); return ask(query(lson(rt),l,mid,x,y),query(rson(rt),mid+1,r,x,y)); } }T; int main() { // #define Isaac #ifdef Isaac freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif int n,m,pd,l,r,i; cin>>(s+1)>>n>>m; len=strlen(s+1); for(i=1;i<=n;i++) cin>>a[i]; T.build(1,1,n); for(i=1;i<=m;i++) { cin>>pd>>l>>r; if(pd==1) { T.update(1,1,n,l,r); } else { cout<<T.query(1,1,n,l,r)<<endl; } } return 0; }
P902. 水果店
总结
- 开题顺序:
题罚坐两小时推逆运算没推出来。
后记
-
题目中错别字较多,部分定义冗杂且陈述不清,存在歧义
-
数据范围分成了两部分,一半在输入格式里,一半在提升里。 -
因之前基本都写过遂找 删了,题目背景留作存档。
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18697563,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)