luogu1903
(带修莫队题....有点卡常需要调整块的大小....最合适的位置为sz=(n^(2/3)),可通过基本不等式证明,(明天补树套树做法
题解:权值很小,数组可解决(权值过大应该考虑离散化),然后就是基本带修操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | #include <bits/stdc++.h> #define ll long long #define s second #define f first #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) const int MAXN=5e4+10; const int NM=1e6+100; using namespace std; ll read(){ ll x=0,f=1; char ch= getchar (); while (! isdigit (ch)){ if (ch== '-' )f=-1;ch= getchar ();} while ( isdigit (ch))x=x*10+ch- '0' ,ch= getchar (); return f*x; } int n,m; int a[MAXN],b[MAXN]; typedef struct node{ int pos,x,y; }node; node d1[MAXN],d2[MAXN]; int p[MAXN],flag[NM]; typedef struct Node{ int l,r,t,id; friend bool operator<(Node aa,Node bb){ if (p[aa.l]==p[bb.l]&&p[aa.r]==p[bb.r]) return aa.t<bb.t; else if (p[aa.l]==p[bb.l]) return p[aa.r]<p[bb.r]; else return p[aa.l]<p[bb.l]; } }Node; Node que[MAXN]; int ans[MAXN],ans1; void join( int l, int r, int pos){ if (l<=d1[pos].pos&&d1[pos].pos<=r){ flag[d1[pos].x]--; if (!flag[d1[pos].x])ans1--; flag[d1[pos].y]++; if (flag[d1[pos].y]==1)ans1++; } a[d1[pos].pos]=d1[pos].y; } void erase( int l, int r, int pos){ if (l<=d2[pos].pos&&d2[pos].pos<=r){ flag[d2[pos].x]--; if (!flag[d2[pos].x])ans1--; flag[d2[pos].y]++; if (flag[d2[pos].y]==1)ans1++; } a[d2[pos].pos]=d2[pos].y; } int main(){ n=read(),m=read(); int sz=( int ) pow (n,2.0/3); for ( int i=1;i<=n;i++)p[i]=(i-1)/sz+1; inc(i,1,n)a[i]=read(),b[i]=a[i]; int t=0,pos,vul; char ch; int cnt=0; for ( int i=1;i<=m;i++){ scanf ( " %c" ,&ch); if (ch== 'Q' ){ que[++cnt].l=read();que[cnt].r=read();que[cnt].id=i;que[cnt].t=t; } else { t++;pos=read(),vul=read(); d1[t].pos=pos;d1[t].x=b[pos];d1[t].y=vul; d2[t].pos=pos;d2[t].x=vul;d2[t].y=b[pos]; b[pos]=vul; } ans[i]=-1; } sort(que+1,que+cnt+1); int L=1,R=0,T=0;ans1=0; for ( int i=1;i<=cnt;i++){ while (que[i].t<T){ erase(L,R,T);T--; } while (que[i].t>T){ T++;join(L,R,T); } while (que[i].l>L){ flag[a[L]]--; if (!flag[a[L]])ans1--; L++; } while (que[i].l<L){ L--;flag[a[L]]++; if (flag[a[L]]==1)ans1++; } while (que[i].r<R){ flag[a[R]]--; if (!flag[a[R]])ans1--; R--; } while (que[i].r>R){ R++;flag[a[R]]++; if (flag[a[R]]==1)ans1++; } ans[que[i].id]=ans1; } for ( int i=1;i<=m;i++) if (ans[i]>=0) printf ( "%d\n" ,ans[i]); return 0; } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· 一个基于 .NET 开源免费的异地组网和内网穿透工具
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单