多校A层冲刺NOIP2024模拟赛25
他怎么把贴吧封了啊啊啊啊……
图
签到题,bitset水过就行了。
点此查看代码
#include<bits/stdc++.h> using namespace std; #define rep(i,s,t,p) for(int i = s;i <= t; i += p) #define drep(i,s,t,p) for(int i = s;i >= t; i -= p) #ifdef LOCAL FILE *InFile = freopen("in.in","r",stdin),*OutFile = freopen("out.out","w",stdout); #else // FILE *InFile = stdin,*OutFile = stdout; FILE *InFile = freopen("a.in","r",stdin),*OutFile = freopen("a.out","w",stdout); #endif using ll=long long;using ull=unsigned long long; using db = double;using ldb = long double; const int N = 1e4 + 10; int n,m;char s[N]; bitset<N> e[N]; inline void solve(){ cin>>n>>m; rep(test,1,m,1){ cin>>(s+1); bitset<N> S,T; rep(i,1,n,1){ if(s[i] == '1' || s[i] == '3') T.set(i); if(s[i] == '2' || s[i] == '3') S.set(i); } rep(i,1,n,1){ if(s[i] == '1') e[i] ^= S; if(s[i] == '2') e[i] ^= T; if(s[i] == '3') e[i] ^= S|T; } } ll ans = 0; rep(i,1,n,1){ ans += e[i].count(); if(e[i][i]) ans--; } cout<<ans/2; } signed main(){ cin.tie(nullptr)->sync_with_stdio(false); solve(); }
序列
所有正解都因为没有特判or精度炸掉了,只有我一个过的,乐。讲一个可能与正解不同的做法(因为赛后看那么多正解被疯狂hack不止,所以没看,如果一样的话请告诉我这个唐氏),没有什么特判与炸int/long long的问题,但常数稍大。
操作的贪心策略和只有一次赋值操作比较显然,就不说了。
记jiashu),
考虑每种操作带来的贡献。
- 赋值操作:如果将
,赋值前 ,赋值后 ,有 。 - 加操作:等价于将
,加之前 ,加之后 ,有 。 - 乘操作,等价于将
,乘之前 ,乘之后 ,有 。
发现
时间复杂度
点此查看代码
#include<bits/stdc++.h> using namespace std; #define rep(i,s,t,p) for(int i = s;i <= t; i += p) #define drep(i,s,t,p) for(int i = s;i >= t; i -= p) #ifdef LOCAL FILE *InFile = freopen("in.in","r",stdin),*OutFile = freopen("out.out","w",stdout); #else // FILE *InFile = stdin,*OutFile = stdout; FILE *InFile = freopen("b.in","r",stdin),*OutFile = freopen("b.out","w",stdout); #endif using ll=long long;using ull=unsigned long long; using db = double;using ldb = long double; #define pii pair<db,int> constexpr int N = 1e5 + 10,mod = 1e9 + 7; int n,m,a[N];ll ad[N],mul[N],fz[N]; struct Segment_Tree{ struct segment_tree{ int l,r,val; #define l(x) tree[x].l #define r(x) tree[x].r #define val(x) tree[x].val }tree[N<<2]; inline void pushup(int k){val(k) = 1ll*val(k<<1)*val(k<<1|1)%mod;} void build(int k,int l,int r){ l(k) = l,r(k) = r; if(l == r) return val(k) = a[l],void(); int mid = (l + r) >> 1; build(k<<1,l,mid);build(k<<1|1,mid+1,r); pushup(k); } void upd(int k,int pos,int val){ if(l(k) == r(k)) return val(k) = val,void(); int mid = (l(k) + r(k)) >> 1; if(pos <= mid) upd(k<<1,pos,val);else upd(k<<1|1,pos,val); pushup(k); } inline int qry(){return val(1);} #undef val #undef l #undef r }T; priority_queue<int> op[N][4]; struct frac{ ll z,m;frac(){} frac(ll Z,ll M){ll gcd = __gcd(Z,M);z = Z/gcd;m = M/gcd;} friend bool operator <= (const frac &x,const int &y){return x.z <= y*x.m;} bool operator == (const frac &x)const{return z == x.z && m == x.m;} bool operator < (const frac &x) const{return z*x.m < x.z*m;} }; struct node{ frac del;int p,flag; node(frac D,int P,int F):del(D),p(P),flag(F){} bool operator < (const node &x) const {if(del == x.del)if(p == x.p) return flag < x.flag;else return p < x.p;else return del < x.del;} }; set<node> q; inline void solve(){ cin>>n>>m;rep(i,1,n,1) cin>>a[i],fz[i] = a[i],mul[i] = 1,ad[i] = 0;T.build(1,1,n); auto ins = [&](int opr,int x,int y){ if(opr == 1 && y <= a[x]) return; if(opr == 3 && y == 1) return; switch(opr){ case 1:if(op[x][1].empty()) op[x][1].emplace(y);else if(op[x][1].top() < y) op[x][1].pop(),op[x][1].emplace(y);break; case 2:op[x][2].emplace(y);break; case 3:op[x][3].emplace(y);break; } }; auto get = [&](int p){return (fz[p]+ad[p]%mod)*mul[p]%mod;}; auto Ins = [](int p){ if(op[p][1].size()) q.emplace(frac((op[p][1].top()-fz[p]),(fz[p]+ad[p])),p,1); if(op[p][2].size()) q.emplace(frac(op[p][2].top(),(fz[p]+ad[p])),p,2).second; if(op[p][3].size()) q.emplace(frac(op[p][3].top()-1,1),p,3); }; rep(i,1,m,1){int op,x,y;cin>>op>>x>>y;ins(op,x,y);} rep(i,1,n,1) Ins(i); cout<<T.qry()<<' '; int now = m+1; rep(test,1,m,1){ if(q.empty() || (*q.rbegin()).del < frac(0,1)){now = test;break;} auto p = (*q.rbegin()).p; auto d = (*q.rbegin()).del; auto flag = (*q.rbegin()).flag;q.erase(--q.end()); if(flag == 1){ auto x = op[p][1].top();op[p][1].pop(); if(op[p][2].size()) q.erase(node(frac(op[p][2].top(),(fz[p]+ad[p])),p,2)); if(op[p][3].size()) q.erase(node(frac(op[p][3].top()-1,1),p,3)); fz[p] = x;T.upd(1,p,get(p)); } else if(flag == 2){ auto x = op[p][2].top();op[p][2].pop(); if(op[p][1].size()) q.erase(node(frac((op[p][1].top()-fz[p]),(fz[p]+ad[p])),p,1)); if(op[p][3].size()) q.erase(node(frac(op[p][3].top()-1,1),p,3)); ad[p] += x;T.upd(1,p,get(p)); } else{ auto x = op[p][3].top();op[p][3].pop(); if(op[p][1].size()) q.erase(node(frac((op[p][1].top()-fz[p]),(fz[p]+ad[p])),p,1)); if(op[p][2].size()) q.erase(node(frac(op[p][2].top(),(fz[p]+ad[p])),p,2)); mul[p] = mul[p]*x%mod;T.upd(1,p,get(p)); } Ins(p);cout<<T.qry()<<' '; } rep(i,now,m,1) cout<<T.qry()<<' '; } signed main(){ cin.tie(nullptr)->sync_with_stdio(false); solve(); }
树
改不完啊……
字符串
发现将答案就是将
考虑如何求逆序对数,发现值域很小,考虑对值域做点什么。
设
然后直接放在线段树上跑就行了,时间复杂度
点此查看代码
#include<bits/stdc++.h> using namespace std; #define rep(i,s,t,p) for(int i = s;i <= t; i += p) #define drep(i,s,t,p) for(int i = s;i >= t; i -= p) #ifdef LOCAL FILE *InFile = freopen("in.in","r",stdin),*OutFile = freopen("out.out","w",stdout); #else // FILE *InFile = stdin,*OutFile = stdout; FILE *InFile = freopen("d.in","r",stdin),*OutFile = freopen("d.out","w",stdout); #endif using ll=long long;using ull=unsigned long long; using db = double;using ldb = long double; const int N = 2e5 + 10; int n,m,k,a[N],b[N];char s[N],t[N]; struct Segment_Tree{ struct node{ array<array<int,10>,10> v; int l,r; node(){memset(v.data(),0,sizeof(v));} inline void operator += (int val){ array<array<int,10>,10> res; rep(i,0,k-1,1) rep(j,0,k-1,1) res[(i+val)%k][(j+val)%k] = v[i][j]; v = move(res);l = (l + val)%k,r = (r + val)%k; } inline friend node operator + (const node &x,const node &y){ node res;res.l = x.l,res.r = y.r; rep(i,0,k-1,1) rep(j,0,k-1,1) res.v[i][j] = x.v[i][j] + y.v[i][j]; res.v[x.r][y.l]++; return res; } }; struct segment_tree{ int l,r,lz;node val; #define l(x) tree[x].l #define r(x) tree[x].r #define lz(x) tree[x].lz #define val(x) tree[x].val }tree[N<<2]; inline void pushup(int k){val(k) = val(k<<1) + val(k<<1|1);} inline void pushdown(int p){ if(!lz(p)) return; int ls = p<<1,rs = p<<1|1; val(ls) += lz(p);val(rs) += lz(p); lz(ls) += lz(p);lz(rs) += lz(p);lz(p) = 0; lz(ls) %= k,lz(rs) %= k; } void build(int k,int l,int r){ l(k) = l,r(k) = r,lz(k) = 0; if(l == r) return val(k).l = val(k).r = a[l],void(); int mid = (l + r) >> 1; build(k<<1,l,mid);build(k<<1|1,mid+1,r);pushup(k); } void upd(int p,int l,int r,int val){ if(l <= l(p) && r(p) <= r) return val(p) += val,lz(p) += val,lz(p) %= k,void(); int mid = (l(p) + r(p)) >> 1;pushdown(p); if(l <= mid) upd(p<<1,l,r,val); if(r > mid) upd(p<<1|1,l,r,val); pushup(p); } node qry(int k,int l,int r){ if(l <= l(k) && r(k) <= r) return val(k); int mid = (l(k) + r(k)) >> 1;pushdown(k); if(r <= mid) return qry(k<<1,l,r); if(l > mid) return qry(k<<1|1,l,r); return qry(k<<1,l,r)+qry(k<<1|1,l,r); } }T; inline void solve(){ auto change = [&](int *a,char *s,int len){rep(i,0,len,1) a[i] = s[i] - 'a';}; cin>>n>>m>>k>>(s+1);change(a+1,s+1,strlen(s+1));T.build(1,1,n); rep(test,1,m,1){ int op,l,r,x;cin>>op>>l>>r; if(op == 1) cin>>x,T.upd(1,l,r,x); else{ cin>>t;auto res = T.qry(1,l,r).v; change(b,t,k-1); int ans = 0; rep(i,0,k-1,1) rep(j,0,i,1) ans += res[b[i]][b[j]]; cout<<ans+1<<'\n'; } } } signed main(){ cin.tie(nullptr)->sync_with_stdio(false); solve(); }
p
挂个万穗爷。我也想被万穗爷抱着睡
__________________________________________________________________________________________
本文来自博客园,作者:CuFeO4,转载请注明原文链接:https://www.cnblogs.com/hzoi-Cu/p/18561492
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!