根据http://blog.csdn.net/w00w12l/article/details/8212782这个博客学习了一些知识,做了一些题目。(第一篇博客,多多指教,看了别人的思路,算不上原创)
1、POJ 2299 Ultra-QuickSort
http://acm.pku.edu.cn/JudgeOnline/problem?id=2299
求逆序数,离散化,降序。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX = 500000+10;
struct node
{
int num;
int id;
}a[MAX];
int n, b[MAX], c[MAX];
bool operator<(const node&p1, const node&p2)
{
return p1.num > p2.num;
}
int lowbit(int x)
{
return x&(-x);
}
void update(int x, int t)
{
while (x<=n)
{
c[x] += t;
x += lowbit(x);
}
}
int getsum(int x)
{
int sum = 0;
while (x)
{
sum += c[x];
x -= lowbit(x);
}
return sum;
}
int main()
{
int i, j;
__int64 ans;
while (scanf("%d",&n) == 1, n)
{
ans = 0;
for (i=1; i<=n; i++)
{
scanf("%d", &a[i].num);
a[i].id = i;
}
sort(a+1, a+n+1);
for (i=1; i<=n; i++)
{
b[a[i].id] = i;
}
memset(c, 0, sizeof(c));
for (i=1; i<=n; i++)
{
//printf("%d ", a[i].id);
ans += getsum(b[i]);
update(b[i], 1);
}
printf("%I64d\n", ans);
}
return 0;
}
2、POJ 2352 Stars
http://acm.pku.edu.cn/JudgeOnline/problem?id=2352
#include <cstdio>
#include <cstring>
const int MAX = 32000+10;
int x[MAX/2], y, c[MAX], leave[MAX];
int lowbit(int x)
{
return x&(-x);
}
void update(int x, int t)
{
while (x<=MAX)
{
c[x] += t;
x += lowbit(x);
}
}
int getsum(int x)
{
int sum = 0;
while (x)
{
sum += c[x];
x -= lowbit(x);
}
return sum;
}
int main()
{
int n, i;
while (scanf("%d", &n) == 1)
{
memset(c, 0, sizeof(c));
memset(leave, 0, sizeof(leave));
for (i=1; i<=n; i++)
{
scanf("%d%d", &x[i], &y);
x[i]++;
leave[getsum(x[i])]++;
update(x[i], 1);
}
for (i=0; i<n; i++)
{
printf("%d\n", leave[i]);
}
}
return 0;
}
3、poj2481Cows
http://poj.org/problem?id=2481
大体意思是给一些线段,询问每一个线段包含于多少个线段,先按线段左端降序排列,然后利用树桩数组统计比当前线段右端大的线段数即可。注意线段相等的情况。
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX = 100000 + 10;
struct rang
{
int x;
int y;
int id;
}cow[MAX];
int n, ans[MAX], c[MAX];
bool flag[MAX];
bool operator<(const rang& a, const rang& b)
{
return a.y>b.y || a.y == b.y && a.x < b.x;
}
bool operator==(const rang&a, const rang&b)
{
return a.x == b.x && a.y == b.y;
}
int lowbit(int x)
{
return x&(-x);
}
void update(int x, int v)
{
while (x<MAX)
{
c[x] += v;
x += lowbit(x);
}
}
int getsum(int x)
{
int sum = 0;
while (x)
{
sum += c[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
int i;
while (scanf("%d", &n) == 1, n)
{
memset(c, 0, sizeof(c));
memset(flag, false, sizeof(flag));
for (i=1; i<=n; i++)
{
scanf("%d%d",&cow[i].x, &cow[i].y);
cow[i].x++;
cow[i].y++;
cow[i].id = i;
}
sort(cow+1, cow+n+1);
for (i=2; i<=n; i++)
{
if (cow[i] == cow[i-1])
{
flag[i] = true;
}
}
for (i=1; i<=n; i++)
{
//ans[cow[i].id] = i-1 - getsum(cow[i].y-1);
//printf("\n%d %d\n", cow[i].x, cow[i].y);
if (!flag[i])
{
ans[cow[i].id] = getsum(cow[i].x);
}
else
{
ans[cow[i].id] = ans[cow[i-1].id];
}
update(cow[i].x, 1);
}
for (i=1; i<n; i++)
{
printf("%d ",ans[i]);
}
printf("%d\n", ans[i]);
}
return 0;
4、soj4122
上一题的变形,询问一个点在多少个线段内,涉及到成段更新,单点查询,update函数更新段,getsum函数单点查询。
http://cstest.scu.edu.cn/soj/problem.action?id=4122
/*
ID: lj104302
LANG: C++
TASK:
*/
/*
next_permutation prev_permutation
max_element min_element
nth_element
binary_search upper_bound lower_bound
to_string <char, char_traits <char> , allocator <char> > ()
<cstdlib> atoi, atof, atol,
sscanf, sprintf
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstddef>
#include <cctype>
#include <cassert>
#include <map>
#include <set>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <bitset>
#include <utility>
#include <iomanip>
#include <algorithm>
#define eps 1e-10
#define inf 0x7fffffff
using namespace std;
typedef long long int64;
const int MAX = 100001;
int n, m, beg, end;
struct node
{
int l;
int r;
int cnt;
}no[MAX*8+8];
void bulid(int l, int r, int lev)
{
no[lev].l = l;
no[lev].r = r;
no[lev].cnt = 0;
if (l == r)
{
return;
}
int mid = (l+r) / 2;
bulid(l, mid, lev * 2);
bulid(mid+1, r, lev*2+1);
}
void insert(int l, int r, int lev)
{
if (l==no[lev].l && r == no[lev].r)
{
no[lev].cnt++;
return;
}
int mid = (no[lev].l + no[lev].r) / 2;
if (r <= mid)
{
insert(l, r, lev*2);
}
else if (l>mid)
{
insert(l, r, lev*2+1);
}
else
{
insert(l, mid, lev*2);
insert(mid+1, r, lev*2+1);
}
}
int query(int val, int pos)
{
int ans = 0;
if (val>=no[pos].l && val<=no[pos].r)
{
ans += no[pos].cnt;
//int mid = (no[pos].r + no[pos].l) / 2;
}
if (no[pos].l == no[pos].r)
{
return ans;
}
int mid = (no[pos].r + no[pos].l) / 2;
if (val <= mid)
{
ans += query(val, pos*2);
}
else
{
ans += query(val, pos*2+1);
}
return ans;
}
int main()
{
/****************************/
#ifndef ONLINE_JUDGE
freopen("F:\\program study\\ACM\\1.in","r",stdin);
freopen("F:\\program study\\ACM\\1.out","w",stdout);
#endif
/****************************/
int cas;
cin >> cas;
while (cas--)
{
cin >> n >> m;
bulid(1, MAX*2, 1);
while (n--)
{
cin >> beg >> end;
insert(beg+MAX, end+MAX, 1);
}
while (m--)
{
int t;
cin >> t;
cout << query(t+MAX, 1) << endl;
}
}
/****************************/
#ifndef ONLIINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
/****************************/
return 0;
}