zoukankan      html  css  js  c++  java
  • Hdu5517 Triple

    Description

    Given the finite multi-set (A) of (n) pairs of integers, an another finite multi-set (B) of (m) triples of integers, we define the product of (A) and (B) as a multi-set

    [C=A∗B=lbrace langle a,c,d angle mid langle a,b angle in A, langle c,d,e angle in B ; and ; b=e brace ]

    For each ⟨a,b,c⟩∈C, its BETTER set is defined as

    [BETTER_{C}(langle a,b,c angle )=lbrace langle u,v,w angle in C mid langle u,v,w angle eq langle a,b,c angle, u ge a, v ge b, w ge c brace ]

    As a multi-set of triples, we define the TOP subset (as a multi-set as well) of (C), denoted by (TOP(C)), as

    [TOP(C)=lbrace langle a,b,c angle in C mid BETTER_{C}(langle a,b,c angle brace ) = phi ]

    You need to compute the size of (TOP(C)).

    Input

    The input contains several test cases. The first line of the input is a single integer (t (1 le t le 10)) which is the number of test case. Then (t) test cases follow.
    Each test case contains three lines. The first line contains two integers (n (1 le n le 10^{5})) and (m (1 le m le 10^{5})) corresponding to the size of (A) and (B) respectively.
    The second line contains (2 imes n) nonnegative integers (a_{1},b_{1},a_{2},b_{2},cdots,a_{n},b_{n}) which describe the multi-set (A), where (1 le a_{i},b_{i} le 10^{5}).
    The third line contains (3 imes m) nonnegative integers (c_{1},d_{1},e_{1},c_{2},d_{2},e_{3},cdots,c_{m},d_{m},e_{m}) corresponding to the (m) triples of integers in (B), where (1 le c_{i},d_{i} le 10^{3}) and (1 le e_{i} le 10^{5}).

    Output

    For each test case, you should output the size of set (TOP(C)).

    Sample Input

    2
    5 9
    1 1 2 2 3 3 3 3 4 2
    1 4 1 2 2 1 4 1 1 1 3 2 3 2 2 4 1 2 2 4 3 3 2 3 4 1 3
    3 4
    2 7 2 7 2 7
    1 4 7 2 3 7 3 2 7 4 1 7

    Sample Output

    Case #1: 5
    Case #2: 12

    首先对于二元组(langle a_{1},b angle,langle a_{2},b angle dots)我肯定直选(a)最大的与(B)集合中的元素配对。不妨设最大的为(a_{1}),若我选择了(a_{i})配对,那么$$langle a_{1},c,d angle in BETTER_{C}langle a_{i},b,c angle$$
    所以(C)中有用的元素减少到了(O(N))个。之后就是要找的极大的三元组的个数,这个CDQ分治或者二维树状数组都行(就是最大非升子序列长度为(1)的元素个数)。

    #include<iostream>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    
    typedef long long ll;
    #define lowbit(a) (a&(-a))
    #define maxm (1010)
    #define maxn (100010)
    int T,tot,cnt,N,M,A[maxn],nA[maxn],tree[maxm][maxm]; ll ans;
    struct node { int a,b; }; vector <node> B[maxn];
    struct mode
    {
    	int a,b,c; ll num;
    	friend inline bool operator <(const mode &x,const mode &y)
    	{
    		if (x.a != y.a) return x.a < y.a;
    		else
    		{
    			if (x.b != y.b) return x.b < y.b;
    			else return x.c < y.c;
    		}
    	}
    	friend inline bool operator ==(const mode &x,const mode &y) { return x.a == y.a&&x.b == y.b&&x.c == y.c; }
    }C[maxn],bac[maxn]; 
    
    inline bool cmp(int x,int y) { return x > y; }
    
    inline void ins(int i,int y)
    {
    	for (;i <= 1000;i += lowbit(i))
    		for (int j = y;j <= 1000;j += lowbit(j)) ++tree[i][j];
    }
    inline int calc(int i,int y)
    {
    	int ret = 0;
    	for (;i;i -= lowbit(i)) for (int j = y;j;j -= lowbit(j)) ret += tree[i][j];
    	return ret;
    }
    
    inline void init()
    {
    	tot = cnt = ans = 0; memset(tree,0,sizeof(tree));
    	for (int i = 1;i <= 100000;++i) A[i] = nA[i] = 0,B[i].clear();
    }
    
    int main()
    {
    	freopen("5517.in","r",stdin);
    	freopen("5517.out","w",stdout);
    	scanf("%d",&T);
    	for (int Cas = 1;Cas <= T;++Cas)
    	{
    		printf("Case #%d: ",Cas);
    		scanf("%d %d",&N,&M); init();
    		for (int i = 1;i <= N;++i)
    		{
    			int a,b; scanf("%d %d",&a,&b);
    			if (a > A[b]) A[b] = a,nA[b] = 1;
    			else if (a == A[b]) nA[b]++;
    		}
    		for (int i = 1;i <= M;++i)
    		{
    			int a,b,c; scanf("%d %d %d",&a,&b,&c);
    			B[c].push_back((node){a,b});
    		}
    		for (int i = 1;i <= 100000;++i)
    			if (A[i]&&!B[i].empty())
    				for (int j = 0,nn = B[i].size();j < nn;++j)
    					bac[++tot] = (mode){A[i],B[i][j].a,B[i][j].b,nA[i]};
    		sort(bac+1,bac+tot+1);
    		for (int i = 1,j;i <= tot;i = j)
    		{
    			for (j = i+1;j <= tot&&bac[j] == bac[i];++j) bac[i].num += bac[j].num;
    			C[++cnt] = bac[i];
    		}
    		for (int i = cnt;i;--i)
    		{
    			int p1 = 1000-C[i].b+1,p2 = 1000-C[i].c+1;
    			if (!calc(p1,p2)) ans += C[i].num; ins(p1,p2);
    		}
    		cout << ans << endl;
    	}
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    PHP中单引号与双引号的区别分析
    utf8_unicode_ci与utf8_general_ci的区别
    [mysql-Ver5.6.23] windows版my.ini配置
    Gateway/Worker模型 数据库使用示例
    php 字符串 以 开头 以结尾 startWith endWith
    MySQL错误ERROR 2002 (HY000): Can't connect to local MySQL server
    vim变ide
    在Vue中使用样式
    Vue指令之`v-model`和`双向数据绑定
    Vue指令之事件修饰符
  • 原文地址:https://www.cnblogs.com/mmlz/p/5961350.html
Copyright © 2011-2022 走看看