18寒假第六测

第一题:乘法修改的线段树

  一定不能将change,modify分类讨论定两个标记,会有顺序影响

  lazy标记一定要long long,又忘了。。。

代码和上一次差不多

第二题:离散暴力,也可以扫描线

  离散时要将格子映射成点,不然会出现以下情况:

  算横着的小矩形宽就是2,算黄色面积宽还是2,因为没有2让3去减

  如果映射成点,就像这样,,放图比较好理解,就像扫描线,一个叶子节点存的是一个左闭右开的区间

也可以离散+扫描线,但还没写出来

#include <bits/stdc++.h>

using namespace std;
#define maxn 1005
int disx[maxn*2],disy[maxn*2],xs[maxn*2],xe[maxn*2],ys[maxn*2],ye[maxn*2];
int totx,toty;
bool st[maxn*2][maxn*2];
void read(int &x){
    int f=1;x=0;char s=getchar();
    while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
    while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
    x*=f;
}
int main()
{
    freopen("area.in","r",stdin);
    freopen("area.out","w",stdout);
    int n;
    read(n);
    for(int i = 1; i <= n; i++){
        read(xs[i]),read(ys[i]),read(xe[i]),read(ye[i]);
        xs[i]-=1,ys[i]-=1;
        disx[++totx]=xs[i],disx[++totx]=xe[i];
        disy[++toty]=ys[i],disy[++toty]=ye[i];
    }
    sort(disx + 1, disx + 1 + totx);
    sort(disy + 1, disy + 1 + toty);
    totx = unique(disx + 1, disx + 1 + totx) - disx - 1;
    toty = unique(disy + 1, disy + 1 + toty) - disy - 1;
    for(int k = 1; k <= n; k++){
        int xn = lower_bound(disx + 1, disx + 1 + totx, xs[k]) - disx;
        int xm = lower_bound(disx + 1, disx + 1 + totx, xe[k]) - disx;
        int yn = lower_bound(disy + 1, disy + 1 + toty, ys[k]) - disy;
        int ym = lower_bound(disy + 1, disy + 1 + toty, ye[k]) - disy;
        for(int i = xn+1; i <= xm; i++)
        for(int j = yn+1; j <= ym; j++)
            st[i][j] = 1;
    }

    long long ans = 0;
    for(int i = 1; i <= totx; i++)
    for(int j = 1; j <= toty; j++)
        if(st[i][j])
          ans += 1LL * (disx[i] - disx[i - 1]) * (disy[j] - disy[j - 1]);
    printf("%I64d\n",ans);
    return 0;
}

第三题:可持久化数组,每次建树logN的空间复杂度,不改变原来的版本

pool大小为N*2+Q*logN,Q为询问次数

#include <bits/stdc++.h>

using namespace std;
#define maxn 100005
#define ll long long
int a[maxn],n,m,s;
void read(int &x){
    int f=1;x=0;char s=getchar();
    while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
    while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
    x*=f;
}

struct Node{
    int v;
    Node *ls, *rs;

}pool[maxn * 32],*tail = pool, *root[maxn];//?

Node * build(int l = 1,int r = n){
    Node *nd = ++tail;
    if(l == r)
        nd->v = a[l];
    else {
        int m = (l + r) >> 1;
        nd->ls = build(l, m);
        nd->rs = build(m + 1, r);
    }
    return nd;
}
#define Ls nd->ls, l, m
#define Rs nd->rs, m+1, r
Node * modify(int delta, int pos, Node *nd, int l = 1, int r = n){
    Node *nnd = ++tail;
    if(l == r) nnd->v = delta;
    else {
        int m = (l + r) >> 1;
        if(pos <= m){
            nnd->rs = nd->rs;
            nnd->ls = modify(delta, pos, Ls);

        }
        if(pos > m){
            nnd->ls = nd->ls;
            nnd->rs = modify(delta, pos, Rs);
        }
    }
    return nnd;
}

int query(int pos, Node *nd, int l = 1, int r = n ){
    if(l == r)
      return nd->v;
    else {
        int m = (l + r) >> 1;
        if(pos <= m)return query(pos, Ls);
        else return query(pos, Rs);
    }
}
Node * print(int pos,Node *nd){
    printf("%d\n",query(pos,nd));
    return nd;
}
int main(){
    freopen("array.in","r",stdin);
    freopen("array.out","w",stdout);
    read(n);
    for(int i = 1; i <= n; i++)
        read(a[i]);
    root[0] = build();
    read(m);
    for(int i = 1; i <= m; i++){
        string opt;
        cin>>opt;
        if(opt[0] == ‘q‘){
            int pos;
            read(pos);
            root[i] = print(pos, root[i - 1]);
        }
        else if(opt[0] == ‘m‘){
            int pos, x;
            read(pos), read(x);
            root[i] = modify(x,pos,root[i - 1]);

        }
        else {
            int t;
            read(t);
            root[i] = root[t];
        }
    }
}

原文地址:https://www.cnblogs.com/EdSheeran/p/8438278.html

时间: 2024-11-09 02:47:14

18寒假第六测的相关文章

18寒假第三测

第一题:找LCA,两点之间的距离=他们各自到起点的距离 - 2*LCA到起点的距离 #include<bits/stdc++.h> using namespace std; const int maxn = 100015, P = 20; int head[2 * maxn],to[2 * maxn],last[2 *maxn],co[2 * maxn],dep[maxn], idx, anc[maxn][P+1],dis[maxn]; void dfs(int u,int from){ //

18寒假第五测

第一题 线段树 树状数组存差b[i] = a[i]-a[i-1],反正是单点查询,我为什么没想到...很傻的用线段树 #include<bits/stdc++.h> using namespace std; #define maxn 100005 #define ll long long int n, m, a[maxn]; struct SegmentTree{ struct node{ ll sum; int lazy; }; node Tree[maxn << 2]; #de

18寒假第一测

猪猪的想法输入文件:thought.in输出文件:thought.out时间限制:1 second空间限制:128 MB题目描述狗蛋养了许多只可爱的猪猪,这些猪猪她萌都有一些奇怪的想法:比如说猪猪喜欢猪猪,猪猪之间的喜欢是一个很有趣的事情--喜欢是可以传递的,例如猪猪喜欢猪猪,猪猪喜欢猪猪,那么可以说猪猪喜欢猪猪.有意思的一点是,她萌不喜欢自恋的猪猪,一旦出现了自恋的猪猪,那么极有可能的是这个团体出现危险.现在给你只猪猪对单方面的关系,请问这个只猪猪组成的团体是否危险呢?是输出Yes ,否输出N

18寒假第二测

第一题:二维树状数组,bit[x][y]表示从(1,1)到(x,y)的和,二维的坐标从一维的推过来,正确性可以用一个递增和一个递减的序列单调性证明,至于构图就当黑箱吧 #include <cstdio> int n, m, q; struct Case1 { int bit[100010]; void modify( int p, int d ) { for( int i = p; i <= m; i += i & -i ) bit[i] += d; } int query( i

18寒假13测

题目名称 buy slide divide 输入 buy.in slide.in divide.in 输出 buy.out slide.out divide.out 每个测试点时限 1秒 1秒 1秒 内存限制 256MB 256MB 256MB 测试点数目 10 10 10 每个测试点分值 10 10 10 是否有部分分 无 无 无 题目类型 传统 传统 传统 buy description: 地主zxr想买一些长方形的土地,所有的土地可以分为若干组,每一组的土地的价格为这一组里的最长的长乘上最

18寒假12测

Day1 题目名称 party array treasure 输入 party.in array.in treasure.in 输出 party.out array.out treasure.out 每个测试点时限 1秒 1秒 1秒 内存限制 64MB 64MB 64MB 测试点数目 10 10 10 每个测试点分值 10 10 10 是否有部分分 无 无 无 题目类型 传统 传统 传统 party 题目描述: 在M公司里,每个人只有一个直属上司(除了boss).这个公司举办派对,每个人可以给派

寒假第六周 2.15 --- 2.21

新的一周^w^ 2.15 hdu Greedy Tino n个w[i],问能否分成相等的两堆,使得每一堆尽量大 不懂,题解说的是双塔dp dp[i][j] 表示前i个搭成两个塔,差值为 j 的,这两个塔的高度的最大和 dp[i+1][j-v] = max(dp[i+1][j-v],dp[i][j]+v) //放在较高的那个塔上 dp[i+1][j+v] = max(dp[i+1][j+v],dp[i][j]+v)//放在较矮的那个塔 dp[i+1][j] = max(dp[i+1][j],dp[

NOI十连测 第六测 T1

思路: 用treap动态维护,记一个sum1,sum2,注意!,写treap如果有删除操作,千万不能把权值相同的分开来..,这在删除的时候会进入死循环,这是一个惨痛的教训... 1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<time.h> 7 #define l

18寒假的数论

1.容斥原理找1到M中与N互质的数 int primes[33], ptot; vector<pair<int,int> > split(int n) { vector<pair<int,int> > stk; for(int i = 2; i * i <= n; i++) { if(n % i == 0) { stk.push_back(make_pair(i, 0));//一维表示因子,二维表示个数 while(n % i == 0) { n /=