bestcoder #16 ( HDU 5088 5087 5086)

hdu 5086

题目虽然和线段是有关,其实是个找规律的题目

以N来找规律

N = 1:出现a1的次数

N = 2:出现a1的次数  出现a2

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#define pi (acos(-1.0))
#define eps (1e-6)
#define inf (1<<28)
#define mod 1000000007
using namespace std;

typedef long long LL;

int main()
{
	int T,j;
	LL sum,num,i,N;

	scanf("%d",&T);
    while(T--)
	{
		sum = 0;
		scanf("%lld",&N);
		for(i=1;i<=N;i++)
		{
			scanf("%lld",&num);
			sum += (((i*(N - (i-1)))%mod) * num) % mod;
		}

		printf("%lld\n",sum%mod);
    }

    return 0;
}


HDU 5087

求最小递增子序列的次最大长度,先要知道LIS的基本算法,然后新增一个数组来记录每个长度对应出现的次数

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#define pi (acos(-1.0))
#define eps (1e-6)
#define inf (1<<28)
#define mod 1000000007
#define MAXN 1010
using namespace std;

typedef long long LL;

LL seqlen[MAXN],seq[MAXN];
LL cnt[MAXN];

int main()
{
	int i,j,k,N;
	LL maxlen;
	int T;

	scanf("%d",&T);
	while(T--)
	{  
		maxlen = 1;

	    scanf("%d",&N);

	    for(i=1;i<=N;i++)
		{
			 scanf("%lld",&seq[i]); 
			 cnt[i] = seqlen[i] = 1;
		}

	    for(i=2;i<=N;i++)
	    {
		   for(j=1;j<=i-1;j++)
		   {
			  if(seq[j]<seq[i])  
			  { 
				 if(seqlen[i] < seqlen[j] + 1)
				 {
						seqlen[i] = seqlen[j] + 1;
						cnt[i] = cnt[j];
				 }
				 else
					 if(seqlen[i] == seqlen[j] + 1)
						 cnt[i] += cnt[j];
			  }
		   }

		   if(seqlen[i]>maxlen)           
			  maxlen=seqlen[i];
	    }

	    LL ans = 0;

	    for(i=1;i<=N;i++)
		{
			if(maxlen == seqlen[i])
			   ans += cnt[i];
		}

	    printf("%lld\n",maxlen - (ans == 1));
	}

	return 0;
}

HDU 5088

题目已经说了是NIM博弈的改编,问题转化为找到给出的n个数中是否存在任意个数的异或为0,存在输出YES 不存在输出no

居然用到了高斯消元法来解决异或,,主要原理就是将每个数看成二进制单独为一行,然后对矩阵进行转化,如果最后矩阵的秩小于行数那么就表示存在异或为0

的数,所以yes,反之no

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#define pi (acos(-1.0))
#define eps (1e-6)
#define inf (1<<28)
#define mod 1000000007
#define MAXN 45
using namespace std;

typedef long long LL;

LL num[MAXN];

void swap(LL &a,LL &b)
{
	LL t = a;
	a  = b;
	b = t;
}

int gauss(int hang,int lie)//高斯消元
{
	int h,l,t_h;
	for(h=0,l=0;h<hang && l<lie;++h,++l)
	{
		for(t_h = h;t_h<hang;t_h++)
			if(num[t_h] & (1LL << l))
				break;
		
		if(t_h == hang)
		{
			--h;
			continue;
		}
		
		swap(num[t_h],num[h]);

		for(int i = h+1;i<hang;i++)
		{
			if(num[i] & (1LL << l))
				num[i] ^= num[h];
		}
		
	}

	return h < hang;//秩小于行数
}

int main()
{
	int i,j,k,N,flag;
	LL temp;
	int T;

	scanf("%d",&T);

	while(T--)
	{
		scanf("%d",&N);
		for(i=0;i<N;i++)
		{
			if(i > 40)
				scanf("%*lld");
			else
			    scanf("%lld",&num[i]);
		}

		if(N > 40)
		{
			printf("Yes\n");
			continue;
		}
		int res = gauss(N,40);
		printf(res==1?"Yes\n":"No\n");
	}

	return 0;
}
这题有个小优化就是,秩 < min (行,列)  所以数最大是1e12 差不多略大于2^40所以,列最多有40列,如果输入的个数超过40那么肯定存在秩小于行的情况



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值