随笔 - 58,  文章 - 0,  评论 - 4,  阅读 - 3296

一、题目描述:

  给你一个长度为 n 的序列 a , 你需要进行 m 次操作。

   1 : l  r  x 

   2 : l  r  x 

  数据范围:1n1×106,m3×103


 二、解题思路:

  分块:(思路当然不是我想出来的qwq)

  为了方便每个区间都能快速查找,首先对每个区间进行排序。

  于是二分查找即可。时间复杂度 O(nlog2n+mnlog2n)


 三、完整代码:

复制代码
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cmath>
 4 #define N 1000010
 5 using namespace std;
 6 char opt;
 7 int n,q,L,R,x,num,len;
 8 int lp[N],rp[N],pos[N],tag[N];
 9 struct Node{
10     int id,val;
11 }a[N];
12 bool cmp(Node d1,Node d2)
13 {
14     return d1.val<d2.val;
15 }
16 void pre_work()
17 {
18     len=sqrt(n);num=n/len;
19     for(int i=1;i<=num;i++)
20         lp[i]=(i-1)*len+1,rp[i]=i*len;
21     if(len*num<n)
22     {
23         num++;rp[num]=n;
24         lp[num]=(num-1)*len+1;
25     }
26     for(int i=1;i<=num;i++)
27         for(int j=lp[i];j<=rp[i];j++)
28             pos[j]=i;
29     for(int i=1;i<=num;i++)
30         sort(a+lp[i],a+rp[i]+1,cmp);
31 }
32 void update(int l,int r,int x)
33 {
34     int p1=pos[l],p2=pos[r];
35     if(p1==p2)
36     {
37         for(int i=lp[p1];i<=rp[p2];i++)
38             if(a[i].id<=r&&a[i].id>=l)
39                 a[i].val+=x;
40     }
41     else
42     {
43         for(int i=p1+1;i<=p2-1;i++)
44             tag[i]+=x;
45         update(l,rp[p1],x);
46         update(lp[p2],r,x);
47     }
48 }
49 int work(int l,int r,int x)
50 {
51     int ans=r+1,rr=r;x-=tag[pos[l]];
52     while(l<=r)
53     {
54         int mid=(l+r)>>1;
55         if(a[mid].val>=x)
56         {
57             ans=mid;
58             r=mid-1;
59         }
60         else    l=mid+1;
61     }
62     return rr-ans+1;
63 }
64 int query(int l,int r,int x)
65 {
66     int p1=pos[l],p2=pos[r],res=0;
67     if(p1==p2)
68     {
69         for(int i=lp[p1];i<=rp[p2];i++)
70             res+=(a[i].id<=r&&a[i].id>=l&&a[i].val+tag[p1]>=x);
71     }
72     else
73     {
74         for(int i=p1+1;i<=p2-1;i++)
75             res+=work(lp[i],rp[i],x);
76         res+=query(l,rp[p1],x);
77         res+=query(lp[p2],r,x);
78     }
79     return res;
80 }
81 int main()
82 {
83     ios::sync_with_stdio(false);
84     cin.tie(0);cout.tie(0);
85     cin>>n>>q;
86     for(int i=1;i<=n;i++)
87         cin>>a[i].val,a[i].id=i;
88     pre_work();
89     for(int i=1;i<=q;i++)
90     {
91         cin>>opt>>L>>R>>x;
92         if(opt=='M')    update(L,R,x);
93         if(opt=='A')    cout<<query(L,R,x)<<'\n';
94     }
95     return 0;
96 }
复制代码

四、写题心得:

  大概这个排序不是很容易想到吧?分块第一题,做个纪念。也收获了一点经验:

  1 =>Exp++!

  2sort(a,b)[a,b)=>Exp++!

  3使 l , r ,=>Exp++!

  加油!拜拜!

posted on   trh0630  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示