【知识】树状数组!

树状数组

P3374 【模板】树状数组 1

#include <bits/stdc++.h> 
using namespace std;
int n,m,tree[2000010];
int lowbit(int k) { return k & -k; }
void add(int x,int k) {
	while(x<=n) {
		tree[x]+=k;
		x+=lowbit(x);
	}
}
int sum(int x) {
	int ans=0;
	while(x!=0) {
		ans+=tree[x];
		x-=lowbit(x);
	}
	return ans;
}
int main() {
	cin>>n>>m;
	for(int i=1; i<=n; i++) {
		int a;
		cin>>a;
		add(i,a);
	}
	for(int i=1; i<=m; i++) {
		int a,b,c;
		cin>>a>>b>>c;
		if(a==1)
			add(b,c);
		if(a==2)
			cout<<sum(c)-sum(b-1)<<endl;
	}
}

P3368 【模板】树状数组 2

#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
ll n,q,mod,x,y,s,inn[500001],tree[500001];
ll lowbit(ll num){
	return num&-num;
}
void add(ll s,ll num){
	for(ll i=s;i<=n;i+=lowbit(i)) tree[i]+=num;
}
ll ask(ll s){
	ll ans=0;
	for(ll i=s;i>=1;i-=lowbit(i)) ans+=tree[i]; 
	return ans;
}
int main(){
	scanf("%lld%lld",&n,&q);
	for(int i=1;i<=n;i++) scanf("%lld",&inn[i]);
	for(int i=1;i<=q;i++){
		scanf("%lld",&mod);
		if(mod==1){
			scanf("%lld%lld%lld",&x,&y,&s);
			add(x,s);
			add(y+1,-s);
		}
		if(mod==2){
			scanf("%lld",&x);
			printf("%lld\n",inn[x]+ask(x));
		}
	}
}

P2344 [USACO11FEB] Generic Cow Protests G

考虑 DP。

fi 表示到 i 的方案书,显然转移 :fi=j=1,sum[i]sum[j]>0i1fj

发现转移需要满足两个条件

  • j<i
  • sum[j]<sum[i]

发现满足二维偏序,于是时间为第一维,值域树状数组维护第二维,边加入变统计答案即可。

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100005, mod = 1e9 + 9;
int n, t[N], dp[N], a[N];
int sum[N], d[N];
void insert(int x, int v) {
	x++;
	for (int i = x; i <= n + 1; i += (i) & (-i))
		t[i] += v, t[i] %= mod;
}
int ask(int x) {
	x++;
	int ans = 0;
	for (int i = x; i > 0; i -= (i) & (-i))
		ans += t[i], ans %= mod;
	return ans;
}

signed main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		sum[i] = sum[i - 1] + a[i];
		d[i] = sum[i];
	}
	sort(d, d + 1 + n);
	int tot = unique(d, d + 1 + n) - d;
	for (int i = 0; i <= n; i++)
		sum[i] = lower_bound(d, d + 1 + tot, sum[i]) - d;

	dp[sum[0]] = 1;
	insert(sum[0], 1);

	for (int i = 1; i <= n; i++) {
		dp[i] = ask(sum[i]);
		insert(sum[i], dp[i]);
	}
    cout << dp[n] << endl;
}

P6186 [NOI Online #1 提高组] 冒泡排序

li 表示 所有 j<iaj>ai 的个数。及逆序对个数

每次冒泡会使每个点的逆序对减一,及变成 max(0,lik)

交换模拟一下可以得到,具体见代码。

所有只需要计算所有 li>k 的贡献即可,因为其他为 0

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define DEBUG(x) cerr << #x << " = " << x << endl
#define ll long long
typedef pair <int, int> PII;
typedef unsigned int uint;
typedef unsigned long long ull;
#define i128 __int128
#define fi first
#define se second
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
#define ClockA clock_t start, end; start = clock()
#define ClockB end = clock(); cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl;
#define int long long
inline int rd(){
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9'){
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
        x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}
#define rd rd()

void wt(int x){
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        wt(x / 10);
    putchar(x % 10 + '0');
    return;
}
void wt(char x){
    putchar(x);
}
void wt(int x, char k){
    wt(x),putchar(k);
}

namespace Star_F{
    const int N = 5e5;
    int n, m, l[N], a[N];
    struct BIT {
        int t[N];
        void ins(int x, int w) {
            x++;
            for (int i = x; i < N; i += (i & (-i)))
                t[i] += w;
        }
        int ask(int x) {
            x++;
            int ans = 0;
            for (int i = x; i > 0; i -= (i & (-i)))
                ans += t[i];
            return ans;
        }
    } T1, T2;
    int opt, k, x;
    void ins(int x, int w) {
        T1.ins(x, w);
        T2.ins(x, x * w);
    }
    void Main(){
        cin >> n >> m;
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            l[i] = T1.ask(n) - T1.ask(a[i]);
            T1.ins(a[i], 1);
        }
        memset(&T1, 0, sizeof(T1));
        for (int i = 1; i <= n; i++)
            ins(l[i], 1);
        for (int i = 1; i <= m; i++) {
            cin >> opt >> x;
            if (opt == 1) {
                ins(l[x], -1), ins(l[x + 1], -1);
                if (a[x] < a[x + 1]) {
                    int vx = l[x], vx1 = l[x + 1];
                    l[x] = vx1;
                    l[x + 1] = vx + 1;
                    ins(l[x], 1), ins(l[x + 1], 1);
                } else {
                    int vx = l[x], vx1 = l[x + 1];
                    l[x] = vx1 - 1;
                    l[x + 1] = vx;
                    ins(l[x], 1), ins(l[x + 1], 1);
                }
                swap(a[x], a[x + 1]);
            } else {
                if (x >= n) {
                    cout << 0 << endl;
                    continue;
                }
                int frt = T2.ask(n) - T2.ask(x - 1);
                int mins = T1.ask(n) - T1.ask(x - 1);
                mins *= x;
                cout << max(0ll, frt - mins) << endl;
            }
        }
    }
}

signed main(){
    // freopen(".in","r",stdin);
    // freopen(".out","w",stdout);
    ClockA;
    int T=1;
    // T=rd;
    while(T--) Star_F::Main();
    // ClockB;
    return 0;
}


/*
*          ▀▀▀██████▄▄▄       _______________
*          ▄▄▄▄▄  █████████▄  /                 \
*         ▀▀▀▀█████▌ ▀▐▄ ▀▐█ | Code has no BUG!  |
*      ▀▀█████▄▄ ▀██████▄██ | _________________/
*       ▀▄▄▄▄▄  ▀▀█▄▀█════█▀ |/
*            ▀▀▀▄  ▀▀███ ▀       ▄▄
*         ▄███▀▀██▄████████▄ ▄▀▀▀▀▀▀█▌   ______________________________
*       ██▀▄▄▄██▀▄███▀ ▀▀████      ▄██  █                               \\
*    ▄▀▀▀▄██▄▀▀▌████▒▒▒▒▒▒███     ▌▄▄▀▀▀▀█_____________________________ //
*    ▌    ▐▀████▐███▒▒▒▒▒▐██▌
*    ▀▄▄▄▄▀   ▀▀████▒▒▒▒▄██▀
*              ▀▀█████████▀
*            ▄▄██▀██████▀█
*          ▄██▀     ▀▀▀  █
*         ▄█             ▐▌
*     ▄▄▄▄█▌              ▀█▄▄▄▄▀▀▄
*    ▌     ▐                ▀▀▄▄▄▀
*     ▀▀▄▄▀     ██
* \  ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
* \- ▌           Name: Star_F              ▀ ▀
*  - ▌                            (o)          ▀
* /- ▌            Go Go Go !               ▀ ▀
* /  ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
*/

P6619 [省选联考 2020 A/B 卷] 冰火战士

简化题意,求:

max(min(iice,xikyi,ifire,xikyi))

由于第一项单调递增,第二项单调递减,所以答案一定为他们的交点,所有二分找交点即可了,树状数组维护。

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define DEBUG(x) cerr << #x << " = " << x << endl
#define ll long long
typedef pair <int, int> PII;
typedef unsigned int uint;
typedef unsigned long long ull;
#define i128 __int128
#define fi first
#define se second
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
#define ClockA clock_t start, end; start = clock()
#define ClockB end = clock(); cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl;
//#define int long long
inline int rd(){
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9'){
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
        x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}
#define rd rd()

void wt(int x){
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        wt(x / 10);
    putchar(x % 10 + '0');
    return;
}
void wt(char x){
    putchar(x);
}
void wt(int x, char k){
    wt(x),putchar(k);
}

namespace Star_F{

    const int N = 2e6 + 100;
    struct BIT {
        int t[N];
        void ins(int x, int w) {
            x++;
            for (int i = x; i < N; i += (i & (-i)))
                t[i] += w;
        }
        int ask(int x) {
            x++;
            int ans = 0;
            for (int i = x; i > 0; i -= (i & (-i)))
                ans += t[i];
            return ans;
        }
        int ask(int x, int y) { return ask(y) - ask(x - 1); }
    } T[2];
    struct Q {
        int op, t, x, y;
    } q[N];
    int d[N], tot;

    void Main(){
        int Q;
        ios::sync_with_stdio(false), cin.tie(0);
        cin >> Q;
        for (int i = 1; i <= Q; i++) {
            cin >> q[i].op >> q[i].t;
            if (q[i].op == 1)
                cin >> q[i].x >> q[i].y, d[++tot] = q[i].x;
        }
        sort(d + 1, d + 1 + tot);
        tot = unique(d + 1, d + 1 + tot) - d - 1;
        for (int i = 1; i <= Q; i++) {
            if (q[i].op == 1)
                q[i].x = lower_bound(d + 1, d + 1 + tot, q[i].x) - d;
        }

        for (int i = 1; i <= Q; i++) {
            auto [op, t, x, y] = q[i];
            if (op == 1) {
                T[t].ins(x, y);
            } else {
                T[q[t].t].ins(q[t].x, -q[t].y);
            }

            int l = 1, r = tot, p1 = 0, p2;
            while (l <= r) {
                int mid = l + r >> 1;

                if (T[0].ask(1, mid) <= T[1].ask(mid, tot))
                    p1 = mid, l = mid + 1;
                else
                    r = mid - 1;
            }

            int w1 = T[0].ask(1, p1), 
            w2 = T[1].ask(p1 + 1, tot);
            p2 = p1;
            l = p1 + 1, r = tot;
            while (l <= r) {
                int mid = l + r >> 1;
                if (T[1].ask(p1 + 1, mid) == 0)
                    l = mid + 1, p2 = mid;
                else
                    r = mid - 1;
            }
            p2++;
            if (max(w1, w2) == 0) {
                cout << "Peace\n";
                continue;
            }
            if (w1 <= w2) {
                cout << d[p2] << " " << 2 * w2 << '\n';
            } else {
                cout << d[p1] << " " << 2 * w1 << '\n';
            }
        }
    }

}

signed main(){
    // freopen(".in","r",stdin);
    // freopen(".out","w",stdout);
    ClockA;
    int T=1;
    // T=rd;
    while(T--) Star_F::Main();
    // ClockB;
    return 0;
}


/*
*          ▀▀▀██████▄▄▄       _______________
*          ▄▄▄▄▄  █████████▄  /                 \
*         ▀▀▀▀█████▌ ▀▐▄ ▀▐█ | Code has no BUG!  |
*      ▀▀█████▄▄ ▀██████▄██ | _________________/
*       ▀▄▄▄▄▄  ▀▀█▄▀█════█▀ |/
*            ▀▀▀▄  ▀▀███ ▀       ▄▄
*         ▄███▀▀██▄████████▄ ▄▀▀▀▀▀▀█▌   ______________________________
*       ██▀▄▄▄██▀▄███▀ ▀▀████      ▄██  █                               \\
*    ▄▀▀▀▄██▄▀▀▌████▒▒▒▒▒▒███     ▌▄▄▀▀▀▀█_____________________________ //
*    ▌    ▐▀████▐███▒▒▒▒▒▐██▌
*    ▀▄▄▄▄▀   ▀▀████▒▒▒▒▄██▀
*              ▀▀█████████▀
*            ▄▄██▀██████▀█
*          ▄██▀     ▀▀▀  █
*         ▄█             ▐▌
*     ▄▄▄▄█▌              ▀█▄▄▄▄▀▀▄
*    ▌     ▐                ▀▀▄▄▄▀
*     ▀▀▄▄▀     ██
* \  ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
* \- ▌           Name: Star_F              ▀ ▀
*  - ▌                            (o)          ▀
* /- ▌            Go Go Go !               ▀ ▀
* /  ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
*/
posted @   Star_F  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
点击右上角即可分享
微信分享提示