zoukankan      html  css  js  c++  java
  • Garlands CodeForces

    Garlands

     CodeForces - 707E 

    题意:一个n * m矩阵,k条链(1 <= n,m,k <= 2000),每条链绑定着一些灯泡,每个灯泡亮着时有权值,灭掉的时候权值为0。一个链条控制其上所有灯泡的亮灭。有两种操作,SWITCH i:按第i条链的开关,开变关,关变开。ASK x1,y1,x2,y2,查询以x1,y1为左上,x2,y2为右下的矩阵的权值。ASK最多2000次

    题解:2000 * 2000 的数据可以使用二维的树状数组,主要是链的保证状态,当状态改变的时候如果关变开明显是加上顶点值,反之减去。在计算矩形的所有顶点值的和时候容斥一下面积就好了

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include<stack>
    #define INF 0x3f3f3f3f
    #define lowbit(x) (x&(-x))
    using namespace std;
    typedef long long LL;
    
    const int MAXN = 2e3 + 10;
    const int MOD = 1e9 + 7;
    
    int n,m,k;
    LL c[MAXN][MAXN];
    struct node
    {
        int len,x,y;
        LL w;
    }Q[MAXN][MAXN];
    int isOn[MAXN * MAXN],last[MAXN * MAXN];
    void init()
    {
        memset(c,0,sizeof c);
        for(int i = 1; i <= n * n; i++)
            isOn[i] = last[i] = 1;
    }
    
    void add(int x,int y,LL val)
    {
        for(int i = x; i <= n; i += lowbit(i))
            for(int j = y;j <= m; j += lowbit(j))
                c[i][j] += val;
    }
    
    LL ask(int x,int y)
    {
        LL ans = 0;
        for(int i = x; i > 0; i -= lowbit(i))
            for(int j = y; j > 0;j -= lowbit(j))
                ans += c[i][j];
        return ans;
    }
    LL all(int x1,int y1,int x2,int y2)
    {
        LL ans = ask(x2,y2) - ask(x2,y1 - 1) - ask(x1 - 1,y2) + ask(x1 - 1,y1 - 1);
        return ans;
    }
    int main()
    {
        scanf("%d %d %d",&n,&m,&k);
        init();
        for(int i = 1; i <= k; i++)
        {
            scanf("%d",&Q[i][0].len);
            for(int j = 1; j <= Q[i][0].len; j++)
            {
                scanf("%d %d %lld",&Q[i][j].x,&Q[i][j].y,&Q[i][j].w);
                add(Q[i][j].x,Q[i][j].y,Q[i][j].w);
            }
        }
        int query;
        scanf("%d",&query);
        char str[50];
        while(query--)
        {
            scanf("%s",str);
            if(str[0] == 'A')
            {
                for(int i = 1; i <= k; i++)
                {
                    if(last[i] != isOn[i])//last和isOn不相同保证了这条链被动过
                    {
                        for(int j = 1; j <= Q[i][0].len; j++)
                        {
                            if(isOn[i])
                                add(Q[i][j].x,Q[i][j].y,Q[i][j].w);//isOn为1代表原先为0,那么这条链上的每一个点都要加上权值
                            else
                                add(Q[i][j].x,Q[i][j].y,-Q[i][j].w);//如果isOn为0代表这条链是关闭的,这条链上的每一个点都减去权值
                        }
                        last[i] = isOn[i]; //将该条链的状态保证,以至于下次改变状态的时候可以知道和原先的状态是不一样的
                    }
                }
                int x1,y1,x2,y2;
                scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
                printf("%lld
    ",all(x1,y1,x2,y2));
            }
            else
            {
                int tk;
                scanf("%d",&tk);
                isOn[tk] ^= 1;  //改变这条链的现有的状态
            }
    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Html5——视频标签使用
    Android的四大组件
    Android 硬编码
    按键事件处理
    android Keycode 完全对照表
    Activity的生命周期
    音乐播放控制
    Android permission 访问权限大全
    制作留言板相关资料
    adb查询log命令
  • 原文地址:https://www.cnblogs.com/smallhester/p/11155803.html
Copyright © 2011-2022 走看看