线段树 刷题记录
BZOJ5334: [Tjoi2018]数学计算
- 不是很裸的线段树,想不到的童鞋看到题解估计会被气死。。。
- 线段树维护操作
- 因为是前缀的乘积所以考虑了一下树状数组,但是有个除余。。所以还是线段树吧
- 代码:
1 #include <bits/stdc++.h> 2 #define nmax 100010 3 #define tn t[node] 4 #define sl (node<<1) 5 #define sr ((node<<1)|1) 6 7 using namespace std; 8 typedef long long ll; 9 struct segt{ 10 int l,r; 11 ll v; 12 }t[nmax*4]; 13 ll mod,n; 14 15 void build(int l,int r,int node){ 16 tn.v=1; 17 tn.l=l; 18 tn.r=r; 19 if(l==r) return; 20 int mid=(l+r)>>1; 21 build(l,mid,sl); 22 build(mid+1,r,sr); 23 } 24 25 void upd(int node,int p,ll x){ 26 if(tn.l==tn.r){ 27 tn.v=x; 28 return; 29 } 30 int mid=(tn.l+tn.r)>>1; 31 if(p<=mid) upd(sl,p,x); 32 else upd(sr,p,x); 33 tn.v = (t[sl].v*t[sr].v) % mod; 34 } 35 36 ll solve(int l,int r,int node){ 37 if(tn.l>=l&&tn.r<=r) return tn.v; 38 int mid=(tn.l+tn.r)>>1; 39 ll ans=1; 40 if(l<=mid) ans = ( ans * solve(l,r,sl) )%mod; 41 if(r>mid) ans = ( ans * solve(l,r,sr) )%mod; 42 return ans; 43 } 44 45 int main(){ 46 int t,op; 47 ll num; 48 cin>>t; 49 while(t--){ 50 scanf("%d%d",&n,&mod); 51 build(1,n,1); 52 for (int i=1; i<=n; i++) { 53 scanf("%d%lld",&op,&num); 54 if(op==1) upd(1,i,num); else upd(1,num,1); 55 printf("%lld\n",solve(1,i,1)); 56 } 57 } 58 return 0; 59 }
POJ2828Buy Tickets
- 从后往前考虑,因为考虑到i的时候i后面的已经处理了,现在假如i后面的都不存在,a[i]=x我们需要寻找的就是第x+1个空位,然后把x放在那个空位上
- 线段树维护区间空位数量
- 代码:
1 #include <cstdio> 2 #include <iostream> 3 #define nmax 200010 4 #define tn t[node] 5 #define sl node<<1 6 #define sr (node<<1)+1 7 8 using namespace std; 9 int a[nmax],b[nmax],ans[nmax]; 10 struct segt{ 11 int l,r,v; 12 }t[nmax*4]; 13 int n,tmp; 14 15 void build(int node,int l,int r){ 16 tn.l=l; 17 tn.r=r; 18 if(l==r) { tn.v=1; return; } 19 int mid=(l+r)>>1; 20 build(sl,l,mid); 21 build(sr,mid+1,r); 22 tn.v=t[sl].v+t[sr].v; 23 } 24 25 int mf(int node,int x){ 26 if(tn.r==tn.l) return tn.r; 27 if(t[sl].v>=x) mf(sl,x); else mf(sr,x-t[sl].v); 28 } 29 30 void upd(int node,int p){ 31 tn.v--; 32 if(tn.l==tn.r) return; 33 int mid=(tn.l+tn.r)>>1; 34 if(p<=mid) upd(sl,p); else upd(sr,p); 35 } 36 37 int main(){ 38 while(scanf("%d",&n)!=EOF){ 39 build(1,1,n); 40 for (int i=1; i<=n; i++) scanf("%d%d",&a[i],&b[i]); 41 for (int i=n; i>=1; i--) { 42 tmp=mf(1,a[i]+1); 43 ans[tmp]=b[i]; 44 upd(1,tmp); 45 } 46 for (int i=1; i<=n; i++) printf("%d ",ans[i]); 47 printf("\n"); 48 } 49 return 0; 50 }