只做出了2题,其中一道还是STL水过的。
A题,并查集(类似08年杭州区域赛的并查集,考虑用用删点的思路把一个点添加到另一个集合,不用合并层优化,否则超时,坑死我了,我考虑了半天优化。。。)。
贴代码
#include <iostream>
#include <stdio.h>
#define N 200001
typedef struct {
int fa;
int cnt;
unsigned long long sum;
}node_t;
node_t a[N];
int n;
int id[N];
int gn;
int father(int x)
{
int i = id[x];
while(a[i].fa != i )
{
i = a[i].fa;
}
return i;
}
void merge(int x, int y, int xx, int yy)
{
int t;
if (a[x].cnt < a[y].cnt)
{
//int i = id[xx];
//while( a[i].fa != i )
//{
// a[i].fa = y;
//}
a[x].fa = y;
a[y].sum += a[x].sum;
a[y].cnt += a[x].cnt;
}
else
{
//int i = id[yy];
//while( a[i].fa != i )
// a[i].fa = x;
a[y].fa = x;
a[x].sum += a[y].sum;
a[x].cnt += a[y].cnt;
}
}
void add(int x, int y, int x1)
{
a[x].cnt -= 1;
a[x].sum -= x1;
a[gn].fa = y;
id[x1] = gn++;
a[y].sum += x1;
a[y].cnt += 1;
}
int total(int y)
{
return a[id[y]].sum;
}
int main()
{
int q;
int sno;
int i;
int x, y;
while(scanf("%d%d", &n, &q) != EOF )
{
gn = n+1;
for ( i = 1; i <= n; ++i )
{
id[i] = i;
a[i].fa = i;
a[i].sum = i;
a[i].cnt = 1;
}
for ( i = 0; i < q; ++i )
{
scanf("%d", &sno);
int x1, x2;
int id;
switch(sno)
{
case 1:// merge two set
scanf("%d%d", &x1, &x2);
x = father(x1);
y = father(x2);
if ( x != y)
merge(x, y, x1, x2);
break;
case 2: // merge p to q set
scanf("%d%d", &x1, &x2);
x= father(x1);
y = father(x2);
if ( x != y )
add(x,y, x1);
break;
case 3:
scanf("%d", &x1);
id = father(x1);
printf("%d %llu\n", a[id].cnt, a[id].sum );
break;
}
}
}
return 0;
}
E题,说是给出10万个数,10万个询问,问第k个数字在序列的位置。
测试数据小于500k,也就是大概3万多个数字和询问。(我测10万,10万的数据是1.6M,所以猜测)
开始考虑用链表+数目标记---》果断超时
然后用快排+扫描--》果断WA,思索半天,用自己写的测试数据找到了错误,快排不是稳定排序啊,位置交换了。。。
最后快要撤了,想到用STL,map<string, int>,string存关键字:"k_num"用下划线将第k个num转换成一个字符串,键值int存位置。所以查询只要构造相应字符串查询就行了。最后0.9S+险过。。
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <algorithm>
#include <hash_map>
#include <string>
#include <map>
using namespace std;
map <string, int> hmap;
int id[1000001];
int main()
{
int n, q;
int x, i, t,j;
int gn;
char buf[20];
string tmp;
while(scanf("%d%d", &n , &q) != EOF)
{
hmap.clear();
memset(id,0,sizeof(id));
for ( i = 1; i <= n; ++i )
{
scanf("%d", &x);
++id[x];
sprintf(buf, "%d_%d", id[x], x);
tmp = buf;
hmap[tmp] = i;
}
for ( i = 0;i < q; ++i )
{
scanf("%d%d", &t, &x);
sprintf(buf, "%d_%d", t, x);
tmp = buf;
if ( hmap[tmp] )
printf("%d\n", hmap[tmp]);
else
printf("0\n");
}
}
return 0;
}