区间信息维护与查询 2016.10.13

1、团队程序设计天梯赛-练习集-L3-002 堆栈

解题思路:

维护区间内点的个数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

#define DEBUG printf("debug\n")

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
char cmd[20];
int N;
stack<int> Stack;

struct SegTree {
    int Left, Right;
    int sum;
};

SegTree Tree[maxn*4];

void Build(int low, int high, int index);
void Update(int target, int add, int index);
int Query(int target, int index);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%d", &N);
    Build(1, maxn, 1);
    int t;
    while (N--) {
        scanf("%s", cmd);
        if (strcmp(cmd, "Push") == 0) {
            scanf("%d", &t);
            Stack.push(t);
            Update(t, 1, 1);
        } else if (strcmp("Pop", cmd) == 0) {
            if (!Stack.empty()) {
                printf("%d\n", Stack.top());
                Update(Stack.top(), -1, 1);
                Stack.pop();
            } else {
                printf("Invalid\n");
            }
        } else {
            int Count = Stack.size();
            if (Count == 0) {
                printf("Invalid\n");
            } else {
                if (Count & 1) {
                    ++Count;
                }
                printf("%d\n", Query(Count>>1, 1));
            }
        }
    }
    return 0;
}

void Build(int low, int high, int index)
{
    Tree[index].sum = 0;
    Tree[index].Left = low;
    Tree[index].Right = high;
    if (low == high) {
        return;
    }
    int mid = (low+high) / 2;
    Build(low, mid, index*2);
    Build(mid+1, high, index*2+1);
}

void Update(int target, int add, int index)
{
    if (Tree[index].Left == Tree[index].Right && Tree[index].Left == target) {
        Tree[index].sum += add;
        return;
    }
    int mid = (Tree[index].Left + Tree[index].Right) / 2;
    if (target <= mid) {
        Update(target, add, index*2);
    } else {
        Update(target, add, index*2+1);
    }
    Tree[index].sum = Tree[index*2].sum + Tree[index*2+1].sum;
}

int Query(int target, int index)
{
    if (Tree[index].Left == Tree[index].Right && target <= Tree[index].sum) {
        return Tree[index].Left;
    }
    if (Tree[index*2].sum >= target) {
        return Query(target, index*2);
    } else {
        return Query(target-Tree[index*2].sum, index*2+1);
    }
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
char cmd[20];
int N;
int tree[maxn];
stack<int> Stack;

int lowbit(int x);
void Update(int x, int add);
int Query(int x);
int PeekMedian(int low, int high, int x);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif // __AiR_H
    scanf("%d", &N);
    memset(tree, 0, sizeof(tree));
    int t;
    while (N--) {
        scanf("%s", cmd);
        if (strcmp(cmd, "Push") == 0) {
            scanf("%d", &t);
            Stack.push(t);
            Update(t, 1);
        } else if (strcmp("Pop", cmd) == 0) {
            if (!Stack.empty()) {
                printf("%d\n", Stack.top());
                Update(Stack.top(), -1);
                Stack.pop();
            } else {
                printf("Invalid\n");
            }
        } else {
            int Count = Stack.size();
            if (Count == 0) {
                printf("Invalid\n");
            } else {
                if (Count & 1) {
                    ++Count;
                }
                printf("%d\n", PeekMedian(1, maxn, Count>>1));
            }
        }
    }
    return 0;
}

int lowbit(int x)
{
    return (x&(-x));
}

void Update(int x, int add)
{
    while (x < maxn) {
        tree[x] += add;
        x += lowbit(x);
    }
}

int Query(int x)
{
    int ret = 0;
    while (x > 0) {
        ret += tree[x];
        x -= lowbit(x);
    }
    return ret;
}

int PeekMedian(int low, int high, int x)
{
    if (low == high) {
        return low;
    }
    int mid = (low + high) / 2;
    int t = Query(mid) - Query(low-1);
    if (t >= x) {
        return PeekMedian(low, mid, x);
    } else {
        return PeekMedian(mid+1, high, x-t);
    }
}


2、UESTC 1339  郭大侠与线上游戏

如果用线段树和树状数组做的话需要离散化一下

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e6 + 10;
int cmd[maxn][2];
queue<int> Q;
map<int, int> Map;
int key[maxn];

struct SegTree {
    int Left, Right;
    int sum;
};

SegTree Tree[maxn*5];

void Build(int low, int high, int index);
void Update(int target, int add, int index);
int Query(int target, int index);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif // __AiR_H
    int n;
    scanf("%d", &n);
    Build(1, maxn, 1);
    for (int i = 0; i < n; ++i) {
        scanf("%d", &cmd[i][0]);
        if (cmd[i][0] == 1) {
            scanf("%d",&cmd[i][1]);
            if (Map[cmd[i][1]] == 0) {
                Map[cmd[i][1]] = 1;
            }
        }
    }
    map<int, int>::iterator itr;
    int id = 1;
    for (itr = Map.begin(); itr != Map.end(); ++itr) {
        key[id] = itr->first;
        itr->second = id++;
    }
    for (int i = 0; i < n; ++i) {
        if (cmd[i][0] == 1) {
            Q.push(Map[cmd[i][1]]);
            Update(Map[cmd[i][1]], 1, 1);
        } else if (cmd[i][0] == 2) {
            Update(Q.front(), -1, 1);
            Q.pop();
        } else {
            int Size = Q.size();
            printf("%d\n", key[Query(Size/2+1, 1)]);
        }
    }
    return 0;
}

void Build(int low, int high, int index)
{
    Tree[index].sum = 0;
    Tree[index].Left = low;
    Tree[index].Right = high;
    if (low == high) {
        return;
    }
    int mid = (low+high) / 2;
    Build(low, mid, index*2);
    Build(mid+1, high, index*2+1);
}

void Update(int target, int add, int index)
{
    if (Tree[index].Left == Tree[index].Right && Tree[index].Left == target) {
        Tree[index].sum += add;
        return;
    }
    int mid = (Tree[index].Left + Tree[index].Right) / 2;
    if (target <= mid) {
        Update(target, add, index*2);
    } else {
        Update(target, add, index*2+1);
    }
    Tree[index].sum = Tree[index*2].sum + Tree[index*2+1].sum;
}

int Query(int target, int index)
{
    if (Tree[index].Left == Tree[index].Right && target <= Tree[index].sum) {
        return Tree[index].Left;
    }
    if (Tree[index*2].sum >= target) {
        return Query(target, index*2);
    } else {
        return Query(target-Tree[index*2].sum, index*2+1);
    }
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e6 + 10;
int cmd[maxn][2];
queue<int> Q;
vector<int> V;

struct SegTree {
    int Left, Right;
    int sum;
};

SegTree Tree[maxn*4];

int GetId(int x);
void Build(int low, int high, int index);
void Update(int target, int add, int index);
int Query(int target, int index);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif // __AiR_H
    int n;
    scanf("%d", &n);
    Build(1, maxn, 1);
    for (int i = 0; i < n; ++i) {
        scanf("%d", &cmd[i][0]);
        if (cmd[i][0] == 1) {
            scanf("%d",&cmd[i][1]);
            V.push_back(cmd[i][1]);
        }
    }
    sort(V.begin(), V.end());
    V.erase(unique(V.begin(), V.end()), V.end());
    for (int i = 0; i < n; ++i) {
        if (cmd[i][0] == 1) {
            int t = GetId(cmd[i][1]);
            Q.push(t);
            Update(t, 1, 1);
        } else if (cmd[i][0] == 2) {
            Update(Q.front(), -1, 1);
            Q.pop();
        } else {
            int Size = Q.size();
            printf("%d\n", V[Query(Size/2+1, 1)-1]);
        }
    }
    return 0;
}

int GetId(int x)
{
    return (lower_bound(V.begin(), V.end(), x) - V.begin() + 1);
}

void Build(int low, int high, int index)
{
    Tree[index].sum = 0;
    Tree[index].Left = low;
    Tree[index].Right = high;
    if (low == high) {
        return;
    }
    int mid = (low+high) / 2;
    Build(low, mid, index*2);
    Build(mid+1, high, index*2+1);
}

void Update(int target, int add, int index)
{
    if (Tree[index].Left == Tree[index].Right && Tree[index].Left == target) {
        Tree[index].sum += add;
        return;
    }
    int mid = (Tree[index].Left + Tree[index].Right) / 2;
    if (target <= mid) {
        Update(target, add, index*2);
    } else {
        Update(target, add, index*2+1);
    }
    Tree[index].sum = Tree[index*2].sum + Tree[index*2+1].sum;
}

int Query(int target, int index)
{
    if (Tree[index].Left == Tree[index].Right && target <= Tree[index].sum) {
        return Tree[index].Left;
    }
    if (Tree[index*2].sum >= target) {
        return Query(target, index*2);
    } else {
        return Query(target-Tree[index*2].sum, index*2+1);
    }
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e6 + 10;
int cmd[maxn][2];
queue<int> Q;
vector<int> V;
int Tree[maxn<<2];

int GetId(int x);
void Update(int low, int high, int target, int add, int index);
int Query(int low, int high, int target, int index);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
#endif // __AiR_H
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%d", &cmd[i][0]);
        if (cmd[i][0] == 1) {
            scanf("%d",&cmd[i][1]);
            V.push_back(cmd[i][1]);
        }
    }
    sort(V.begin(), V.end());
    V.erase(unique(V.begin(), V.end()), V.end());
    for (int i = 0; i < n; ++i) {
        if (cmd[i][0] == 1) {
            int t = GetId(cmd[i][1]);
            Q.push(t);
            Update(1, maxn, t, 1, 1);
        } else if (cmd[i][0] == 2) {
            Update(1, maxn, Q.front(), -1, 1);
            Q.pop();
        } else {
            int Size = Q.size();
            printf("%d\n", V[Query(1, maxn, Size/2+1, 1)-1]);
        }
    }
    return 0;
}

int GetId(int x)
{
    return (lower_bound(V.begin(), V.end(), x) - V.begin() + 1);
}

void Update(int low, int high, int target, int add, int index)
{
    Tree[index] += add;
    if (low == high) {
        return;
    }
    int mid = (low + high) / 2;
    if (target <= mid) {
        Update(low, mid, target, add, index*2);
    } else {
        Update(mid+1, high, target, add, index*2+1);
    }
}

int Query(int low, int high, int target, int index)
{
    if (low == high) {
        return low;
    }
    int mid = (low + high) / 2;
    if (Tree[index*2] >= target) {
        return Query(low, mid, target, index*2);
    } else {
        return Query(mid+1, high, target-Tree[index*2], index*2+1);
    }
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e6 + 10;
int cmd[maxn][2];
queue<int> Q;
vector<int> V;
int tree[maxn];

int GetId(int x);
int lowbit(int x);
void Update(int x, int add);
int Query(int x);
int PeekMedian(int low, int high, int x);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif // __AiR_H
    int n;
    memset(tree, 0, sizeof(tree));
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%d", &cmd[i][0]);
        if (cmd[i][0] == 1) {
            scanf("%d",&cmd[i][1]);
            V.push_back(cmd[i][1]);
        }
    }
    sort(V.begin(), V.end());
    V.erase(unique(V.begin(), V.end()), V.end());
    for (int i = 0; i < n; ++i) {
        if (cmd[i][0] == 1) {
            int t = GetId(cmd[i][1]);
            Q.push(t);
            Update(t, 1);
        } else if (cmd[i][0] == 2) {
            Update(Q.front(), -1);
            Q.pop();
        } else {
            int Size = Q.size();
            printf("%d\n", V[PeekMedian(1, maxn, Size/2+1)-1]);
        }
    }
    return 0;
}

int GetId(int x)
{
    return (lower_bound(V.begin(), V.end(), x) - V.begin() + 1);
}

int lowbit(int x)
{
    return (x & (-x));
}

void Update(int x, int add)
{
    while (x < maxn) {
        tree[x] += add;
        x += lowbit(x);
    }
}

int Query(int x)
{
    int ret = 0;
    while (x > 0) {
        ret += tree[x];
        x -= lowbit(x);
    }
    return ret;
}

int PeekMedian(int low, int high, int x)
{
    if (low == high) {
        return low;
    }
    int mid = (low + high) >> 1;
    int t = Query(mid) - Query(low-1);
    if (t >= x) {
        return PeekMedian(low, mid, x);
    } else {
        return PeekMedian(mid+1, high, x-t);
    }
}


3、HDU 5726 GCD

官方题解:

http://bestcoder.hdu.edu.cn/blog/2016-multi-university-training-contest-1-solutions-by-hit/

先%一下写标程的大牛,再贴标程

#include <set>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>

#define dprint(expr) fprintf(stderr, #expr " = %d\n", expr)
#define MP make_pair
#define PB push_back

using namespace std;

typedef long long LL;
typedef pair <int, int> PII;

const int N = 1e5 + 7;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-6;
const double PI = acos(-1.0);

vector <PII> gcd[N];

map <int, LL> Ans;

int n;

int num[N];

int main(void){
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
	int T, Test = 0;
	scanf("%d", &T);
	while (T--) {
		//cerr << T << endl;
		scanf("%d", &n);
		for (int i = 1; i <= n; ++i) {
			scanf("%d", &num[i]);
		}
		Ans.clear();
		for (int k = 1; k <= n; ++k) {
			int last = 0;
			for (int i = 0; i < gcd[k - 1].size(); ++i) {
				int u = gcd[k - 1][i].first, v = gcd[k - 1][i].second;
				int g = __gcd(u, num[k]);
				if (g == last) continue;
				last = g;
				gcd[k].PB(MP(g, v));
			}
			if (num[k] != last) {
				gcd[k].PB(MP(num[k], k));
			}
			for (int i = 0; i < gcd[k].size(); ++i) {
				Ans[gcd[k][i].first] += (i == gcd[k].size() - 1 ? k + 1 : gcd[k][i + 1].second) - gcd[k][i].second;
			}
		}
		int Q;
		scanf("%d", &Q);
		printf("Case #%d:\n", ++Test);
		while (Q--) {
			int u, v, k;
			scanf("%d%d", &u, &v);
			for (k = 0; k < gcd[v].size(); ++k)
				if (gcd[v][k].second > u)
					break;
//			for (int i = 0; i < gcd[v].size(); ++i) {
//				printf("%d -> %d\n", i, gcd[v][i]);
//			}
			printf("%d %I64d\n", gcd[v][k - 1].first, Ans[gcd[v][k - 1].first]);
		}
		for (int i = 0; i <= n; ++i)
			gcd[i].clear();
	}
	return 0;
}

对着标程和题解一下午一晚上,加上在纸上乱画、输出中间结果等等尝试,终于看懂了标程,然后照敲了一遍...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
int a[maxn];
int n;
vector<pair<int, int> > gcd[maxn];
map<int, ll> ans;

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    int T;
    scanf("%d", &T);
    int Case = 0;
    while (T--) {
        printf("Case #%d:\n", ++Case);
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
        }
        for (int i= 0; i <= n; ++i) {
            gcd[i].clear();
        }
        ans.clear();
        for (int i = 1; i <= n; ++i) {
            int last = 0;
            for (int j = 0; j < (int)gcd[i - 1].size(); ++j) {
                int t1 = gcd[i-1][j].first, t2 = gcd[i-1][j].second;
                int g = __gcd(t1, a[i]);
                if (g != last) {
                    last = g;
                    gcd[i].push_back(make_pair(g, t2));
                }
            }
            if (a[i] != last) {
                gcd[i].push_back(make_pair(a[i], i));
            }
            for (int j = 0; j < (int)gcd[i].size(); ++j) {
                if (j == (int)gcd[i].size() - 1) {
                    ans[gcd[i][j].first] += i+1 - gcd[i][j].second;
                } else {
                    ans[gcd[i][j].first] += gcd[i][j+1].second - gcd[i][j].second;
                }
            }
        }
        int Q;
        scanf("%d", &Q);
        while (Q--) {
            int l, r;
            scanf("%d%d", &l, &r);
            int Count = 0;
            while (Count < (int)gcd[r].size()) {
                if (gcd[r][Count].second > l) {
                    break;
                }
                ++Count;
            }
            printf("%d %I64d\n", gcd[r][Count-1].first, ans[gcd[r][Count-1].first]);
        }
    }
    return 0;
}

参考: http://blog.csdn.net/queuelovestack/article/details/51958142

发现了一种预处理比较好理解的做法,预处理出来所有 gcd 值在区间出现的次数,然后查询用线段树做

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
int a[maxn];
int n;

struct SegTree {
    int Left, Right;
    int gcd;
};

SegTree Tree[maxn*4];
map<int, ll> ans, Map, Map_t;

void Build(int low, int high, int index);
int Query(int l, int r, int index);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    int T;
    scanf("%d", &T);
    int Case = 0;
    while (T--) {
        ans.clear(), Map.clear(), Map_t.clear();
        printf("Case #%d:\n", ++Case);
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
        }
        Build(1, n, 1);
        map<int, ll>::iterator itr;
        for (int i = 1; i <= n; ++i) {
            ++ans[a[i]];
            ++Map[a[i]];
            for (itr = Map_t.begin(); itr != Map_t.end(); ++itr) {
                int g = __gcd(itr->first, a[i]);
                ans[g] += itr->second;
                Map[g] += itr->second;
            }
            Map_t.clear();
            for (itr = Map.begin(); itr != Map.end(); ++itr) {
                Map_t[itr->first] = itr->second;
            }
            Map.clear();
        }
        int Q;
        scanf("%d", &Q);
        while (Q--) {
            int l, r;
            scanf("%d%d", &l, &r);
            int g = Query(l, r, 1);
            printf("%d %I64d\n", g, ans[g]);
        }
    }
    return 0;
}

void Build(int low, int high, int index)
{
    Tree[index].Left = low, Tree[index].Right = high;
    if (low == high) {
        Tree[index].gcd = a[low];
        return;
    }
    int mid = (low + high) >> 1;
    Build(low, mid, index*2);
    Build(mid+1, high, index*2+1);
    Tree[index].gcd = __gcd(Tree[index*2].gcd, Tree[index*2+1].gcd);
}

int Query(int l, int r, int index)
{
    if (Tree[index].Left == l && Tree[index].Right == r) {
        return Tree[index].gcd;
    }
    int mid = (Tree[index].Left + Tree[index].Right) >> 1;
    if (r <= mid) {
        return Query(l, r, index*2);
    } else if (mid < l) {
        return Query(l, r, index*2+1);
    } else {
        return __gcd(Query(l, mid, index*2), Query(mid+1, r, index*2+1));
    }
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
int a[maxn];
int n;
int Tree[maxn*4];
map<int, ll> ans, Map, Map_t;

void Build(int low, int high, int index);
int Query(int low, int high, int l, int r, int index);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    int T;
    scanf("%d", &T);
    int Case = 0;
    while (T--) {
        ans.clear(), Map.clear(), Map_t.clear();
        printf("Case #%d:\n", ++Case);
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
        }
        Build(1, n, 1);
        map<int, ll>::iterator itr;
        for (int i = 1; i <= n; ++i) {
            ++ans[a[i]];
            ++Map[a[i]];
            for (itr = Map_t.begin(); itr != Map_t.end(); ++itr) {
                int g = __gcd(itr->first, a[i]);
                ans[g] += itr->second;
                Map[g] += itr->second;
            }
            Map_t.clear();
            for (itr = Map.begin(); itr != Map.end(); ++itr) {
                Map_t[itr->first] = itr->second;
            }
            Map.clear();
        }
        int Q;
        scanf("%d", &Q);
        while (Q--) {
            int l, r;
            scanf("%d%d", &l, &r);
            int g = Query(1, n, l, r, 1);
            printf("%d %I64d\n", g, ans[g]);
        }
    }
    return 0;
}

void Build(int low, int high, int index)
{
    if (low == high) {
        Tree[index] = a[low];
        return;
    }
    int mid = (low + high) >> 1;
    Build(low, mid, index*2);
    Build(mid+1, high, index*2+1);
    Tree[index] = __gcd(Tree[index*2], Tree[index*2+1]);
}

int Query(int low, int high, int l, int r, int index)
{
    if (low == l && high == r) {
        return Tree[index];
    }
    int mid = (low + high) >> 1;
    if (r <= mid) {
        return Query(low, mid, l, r, index*2);
    } else if (mid < l) {
        return Query(mid+1, high, l, r, index*2+1);
    } else {
        return __gcd(Query(low, mid, l, mid, index*2), Query(mid+1, high, mid+1, r, index*2+1));
    }
}

4、HDU 5775 Bubble Sort

解题思路:

找到每个值后面比它小的值的个数,加上当前位置为这个值的最右边的位置

最后才想通,赶快树状数组敲了一发。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
#include <bitset>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
int y[maxn];
int c[maxn];
int Left[maxn], Right[maxn];
int n;

int lowbit(int x);
void Update(int x);
int Query(int x);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    int T;
    scanf("%d", &T);
    int Case = 0;
    while (T--) {
        memset(c, 0, sizeof(c));
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &y[i]);
            Left[y[i]] = Right[y[i]] = i;
            if (y[i] < Left[y[i]]) {
                Left[y[i]] = y[i];
            } else if (y[i] > Right[i]) {
                Right[y[i]] = y[i];
            }
        }
        for (int i = n; i >= 1; --i) {
            int t = Query(y[i]);
            if (i+t > Right[y[i]]) {
                Right[y[i]] = i+t;
            }
            Update(y[i]);
        }
        printf("Case #%d: %d", ++Case, abs(Left[1] - Right[1]));
        for (int i = 2; i <= n; ++i) {
            printf(" %d", abs(Left[i] - Right[i]));
        }
        printf("\n");
    }
    return 0;
}

int lowbit(int x)
{
    return (x & (-x));
}

void Update(int x)
{
    while (x < maxn) {
        c[x] += 1;
        x += lowbit(x);
    }
}

int Query(int x)
{
    int ret = 0;
    while (x) {
        ret += c[x];
        x -= lowbit(x);
    }
    return ret;
}

5、HDU 5122 K.Bro Sorting


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <bitset>
#include <ctime>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 3e6 + 10;

int T, N, ans = 0, Case = 0;
int a[maxn], c[maxn];
int lowbit(int x);
void update(int x);
int query(int x);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%d", &T);
    while (T--) {
        scanf("%d", &N);
        memset(c, 0, sizeof(c));
        for (int i = 1; i <= N; ++i) {
            scanf("%d", &a[i]);
        }
        ans = 0;
        for (int i = N; i > 0; --i) {
            if (query(a[i])) {
                ++ans;
            }
            update(a[i]);
        }
        printf("Case #%d: %d\n", ++Case, ans);
    }
    return 0;
}

int lowbit(int x)
{
    return (x & (-x));
}

void update(int x)
{
    while (x < maxn) {
        ++c[x], x += lowbit(x);
    }
}

int query(int x)
{
    int ret = 0;
    while (x > 0) {
        ret += c[x], x -= lowbit(x);
    }
    return ret;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值