• 前缀和、差分、二分


    前缀和

    1. 激光炸弹

    99. 激光炸弹 - AcWing题库

    二维前缀和的模板题

    这里注意一下边长是R 矩形是(R-1)*(R-1)

    1. #include
    2. using namespace std;
    3. const int N=5e3+10;
    4. int point[N][N];
    5. int sum[N][N];
    6. int main()
    7. {
    8. int n,r;
    9. int tx,ty;
    10. cin>>n>>r;
    11. tx=ty=r;
    12. for(int i=0;i
    13. {
    14. int x,y,v;
    15. cin>>x>>y>>v;
    16. x++,y++;
    17. point[x][y]+=v;
    18. tx=max(x,tx);
    19. ty=max(y,ty);
    20. }
    21. for(int i=1;i<=tx;i++)
    22. for(int j=1;j<=ty;j++)
    23. sum[i][j]=point[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
    24. int ans=0;
    25. for(int i=r;i<=tx;i++)
    26. for(int j=r;j<=ty;j++)
    27. ans=max(ans,sum[i][j]-sum[i-r][j]-sum[i][j-r]+sum[i-r][j-r]);
    28. cout<
    29. return 0;
    30. }

    差分

    1. 增减序列

    100. 增减序列 - AcWing题库

    7b264c11d23649aa9a12437c3cc62a5b.png

     则操作数就是max(p,q),结果种数就是abs(p-q)+1

    1. #include
    2. using namespace std;
    3. typedef long long ll;
    4. const int N=1e5+10;
    5. int a[N],b[N];
    6. int n;
    7. int main()
    8. {
    9. scanf("%d",&n);
    10. for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    11. for(int i=1;i<=n;i++) b[i]=a[i]-a[i-1];//b是a的差分
    12. ll p=0,q=0;//p是b中的正数,q是b中的负数
    13. for(int i=2;i<=n;i++)
    14. if(b[i]>0) p+=b[i];
    15. else q-=b[i];
    16. printf("%lld\n",max(p,q));
    17. printf("%lld\n",abs(p-q)+1);
    18. return 0;
    19. }

    二分 

    1.最佳牛围栏

    102. 最佳牛围栏 - AcWing题库

    二分平均值,然后每个数减去平均值,看是否存在连续的长度都是大于等于0的区间,假如有则满足

    1. #include
    2. using namespace std;
    3. typedef long long ll;
    4. const int N=1e5+10;
    5. double a[N],s[N];
    6. int n,m;
    7. bool judge(double mid)
    8. {
    9. for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i]-mid;//预处理出来a[i]-mid的前缀和
    10. double mins=0;//定义前1~i-m中的最小值
    11. for(int i=m;i<=n;i++)
    12. {
    13. mins=min(mins,s[i-m]);//更新最小值
    14. if(s[i]>=mins) return true;//假如这段区间前缀和差值是大于等于0的说明这段区间是满足的
    15. }
    16. return false;//反之不满足
    17. }
    18. int main()
    19. {
    20. scanf("%d%d",&n,&m);
    21. for(int i=1;i<=n;i++) scanf("%lf",&a[i]);
    22. double l=1,r=100000;
    23. while(r-l>1e-5)//比精度多两位
    24. {
    25. double mid=(l+r)/2;
    26. if(judge(mid)) l=mid;//假如满足,则可以扩大
    27. else r=mid;
    28. }
    29. printf("%d\n",(int)(r*1000));
    30. return 0;
    31. }

    2.特殊排序(交互题

    113. 特殊排序 - AcWing题库

    一开始不知道交互式问题怎么写,其实int N 表示N个整数,你只需要返回一个排好序的vector

    样例那里就是

    指的是对于3个数的每组compare
    compare(1,1)=0
    compare(1,2)=1
    compare(1,3)=0
    compare(2,1)=0
    compare(2,2)=0
    compare(2,3)=0
    compare(3,1)=1
    compare(3,2)=1
    compare(3,3)=0

    不需要满足单调性也可二分

    先找小于等于i的数,然后在从前往后交换到r这个位置上即可

    1. // Forward declaration of compare API.
    2. // bool compare(int a, int b);
    3. // return bool means whether a is less than b.
    4. class Solution {
    5. public:
    6. vector<int> specialSort(int N) {
    7. vector<int> res(1,1);//初始化答案,刚开始只有1这个数,长度是1
    8. for(int i=2;i<=N;i++)//枚举剩下的数
    9. {
    10. int l=0,r=res.size()-1;
    11. while(l//二分查找小于i的数
    12. {
    13. int mid=l+r+1>>1;
    14. if(compare(res[mid],i)) l=mid;//假如res[mid]
    15. else r=mid-1;//反之在左边
    16. }
    17. res.push_back(i);//把i放在末尾
    18. for(int j=res.size()-2;j>r;j--) swap(res[j],res[j+1]);//然后把i换到r+1这个位置上
    19. if(compare(i,res[r])) swap(res[r],res[r+1]);//假如r这个位置比我大,说明在r这个位置
    20. }
    21. return res;
    22. }
    23. };

  • 相关阅读:
    17-数据结构-查找-(顺序、折半、分块)
    CTFHub SSRF 题目
    DirectX11 With Windows SDK--19(Dev) 编译Assimp并加载模型、新的Effects框架
    元素的大小和位置
    这样做时间轴,让你的PPT更出彩!
    玻色量子“揭秘”之最大割(Max-Cut)问题与QUBO建模
    修改npm全局安装模式的路径
    编译安装oh-my-zsh
    学信息系统项目管理师第4版系列06_项目管理概论
    Hadoop完全分布式环境搭建
  • 原文地址:https://blog.csdn.net/lee_14141/article/details/127844972