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那么肯定存在秩小于行的情况

被折叠的 条评论
为什么被折叠?



