@exut
2024-10-15T01:28:55.000000Z
字数 1688
阅读 224
刷题
设一个暴力的 表示 操作后可否到达
操作一的 可以直接视为输入的 除 上取整
操作二的乘法显然至少每次会让 ,所以复杂度 是稳稳的
实现就行了,复杂度 ,然后 T 了
考虑设 表示 第一次取到是哪一次操作后,再设 表示在前面操作基础上,用当前操作达到 的最小次数,不可达设为 即可
每次读入先处理 ,再利用 算 ,复杂度
非常智慧的一道题
# include<bits/stdc++.h>using namespace std;#define int long longconst int inf=1e18;int n,m;int dp[100005];int f[100005];signed main(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);cin>>n>>m;for(int i=1;i<=m;i++) dp[i]=inf;for(int zz=1,t,x,y;zz<=n;zz++){cin>>t>>x>>y;double X=x/100000.0;for(int i=1;i<=m;i++){f[i]=(dp[i]==inf?inf:0);}if(t==1) f[(int)ceil(X)]=1;for(int i=1;i<=m;i++){int to=ceil((t==1)?i+X:1.0*i*x/100000.0);if(f[i]!=y and f[i]!=inf and to<=m){f[to]=min(f[to],f[i]+1);}}for(int i=1;i<=m;i++){if(f[i]<=y and dp[i]==inf){dp[i]=zz;}}}for(int i=1;i<=m;i++)cout<<(dp[i]==inf?-1:dp[i])<<" ";}
注意先乘再除不然会掉精
发现 居然不变啊,那容易想到莫队,这个数据范围也很像啊
注意到 等价于 等价于
鄂鄂考虑维护一个异或的前缀和,然后发现题意削弱成了查询区间 内有多少个 满足 ,不妨设 表示前缀异或 的出现次数
#include<bits/stdc++.h>using namespace std;#define int long longstruct node{int l,r,id;}Q[100005];int n,m,k;int bl[100005];int s[100005];int BK;bool cmp(node x,node y){return (bl[x.l]==bl[y.l]?x.r<y.r:x.l<y.l);}int q[500005];int ans[100005];signed main(){q[0]=1;cin>>n>>m>>k;BK=sqrt(n);for(int i=1;i<=n;i++){cin>>s[i];s[i]^=s[i-1];bl[i]=(i-1)/BK+1;}for(int i=1;i<=m;i++){cin>>Q[i].l>>Q[i].r,Q[i].id=i;// Q[i].l--;}int now=0,i=0,j=0;sort(Q+1,Q+m+1,cmp);for(int x=1;x<=m;x++){int l=Q[x].l-1,r=Q[x].r;while(i>l){now+=(q[s[--i]^k]);q[s[i]]++;}while(j<r){now+=(q[s[++j]^k]);q[s[j]]++;}while(i<l){q[s[i]]--;now-=(q[s[i++]^k]);}while(j>r){q[s[j]]--;now-=(q[s[j--]^k]);}ans[Q[x].id]=now;}for(i=1;i<=m;i++)cout<<ans[i]<<"\n";}