目录
contest-1
contest-2
contest-1
1001
【题意】
查询x到y的路径上边的权值能否组成一个三角形
【题解】
【代码】
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
#include<list>
#include <iostream>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const LL mod = 1e9+7;
const int maxn = 100010;
const int maxm = 200010;
int n,m,tol,head[maxn];
struct edge
{
int to,cost,next;
}es[maxm];
void addedge( int u , int v , int w )
{
es[tol].to = v;
es[tol].cost = w;
es[tol].next = head[u];
head[u] = tol++;
}
int fa[maxn],w[maxn],dep[maxn];
void dfs( int u , int f )
{
for ( int i=head[u] ; i!=-1 ; i=es[i].next )
if ( es[i].to!=f )
{
fa[es[i].to] = u,w[es[i].to] = es[i].cost,dep[es[i].to] = dep[u]+1;
dfs ( es[i].to , u );
}
}
int main()
{
for ( int T ; scanf ( "%d" , &T )==1 ; )
{
for ( int Cas=1 ; Cas<=T ; Cas++ )
{
scanf ( "%d" , &n );
tol = 0;
memset ( head , -1 , sizeof(head) );
for ( int i=2 ; i<=n ; i++ )
{
int u,v,w;
scanf ( "%d%d%d" , &u , &v , &w );
addedge( u , v , w );
addedge( v , u , w );
}
dep[1] = 1;
dfs ( 1 , 0 );
int que[55];
printf( "Case #%d:\n" , Cas );
scanf ( "%d" , &m );
for ( int i=1 ; i<=m ; i++ )
{
int u,v,len = 0;
scanf ( "%d%d" , &u , &v );
while ( len<50&&u!=v )
{
if ( dep[u]>dep[v] )
que[len++] = w[u],u=fa[u];
else
que[len++] = w[v],v=fa[v];
}
if ( len==50 )
printf( "Yes\n" );
else
{
bool ok = false;
sort ( que , que+len );
for ( int i=0 ; i<len-2 ; i++ )
if ( que[i]+que[i+1]>que[i+2] )
{
ok = true;
break;
}
if ( ok )
printf( "Yes\n" );
else
printf( "No\n" );
}
}
}
}
return 0;
}
1002
【题意】
N个元素中选出连续的一部分,分成>=S个连续的数目相等的元素集合,要求:
1.每个集合中,相邻两个元素颜色不同,
2.每个集合总长度在[L,R]内
【题解】
【代码】
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e9+7;
const int maxn = 500010;
char s[maxn];
int n,l,r,sl,ans,sum[maxn],last[255],f[maxn<<1];
struct Queue
{
int q[maxn];
int qh,qt;
void Init()
{
memset ( q , 0 , sizeof(q) );
qh = 1;
qt = 0;
}
void Push( int x )
{
q[++qt] = x;
while ( qt>qh&&f[q[qt]]<=f[q[qt-1]] )
q[qt-1]=q[qt],q[qt--]=0;
}
void Move( int x , int len )
{
if ( q[qh]+len-1<x )
q[qh++] = 0;
}
int Top()
{
return q[qh];
}
}Q;
int Query( int len )
{
memset ( f , 0 , sizeof(f) );
for ( int i=n-len+1 ; i<=n ; i++ )
{
memset ( last , 0 , sizeof(last) );
for ( int j=i,t=1; j>0 ; j-=len,t++ )
{
f[j] = min( t-last[s[j]] , f[j+len]+1 );
last[s[j]] = t;
}
}
int ans=0;
Q.Init();
for ( int i=1 ; i<len ; i++ )
Q.Push(i);
for ( int i=len ; i+(sl-1)*len<=n ; i++ )
{
Q.Push(i); Q.Move( i , len );
if ( f[Q.Top()]>=sl )
ans = max ( ans , sum[(i-len+1)+len*f[Q.Top()]-1]-sum[i-len] );
}
return ans;
}
int main()
{
for ( int T ; scanf ( "%d" , &T )==1 ; )
{
for ( int Cas=1 ; Cas<=T ; Cas++ )
{
sum[0] = 0;
scanf( "%d%d%d%d" , &n , &l , &r , &sl );
scanf( "\n" );
for ( int i=1 ; i<=n ; i++ )
s[i] = getchar();
scanf( "\n" );
for ( int i=1 ; i<=n ; i++ )
sum[i] = sum[i-1]+getchar()-'0';
ans = 0;
for ( int i=l ; i<=r ; i++ )
ans = max ( ans , Query(i) );
printf( "%d\n" , ans );
}
}
return 0;
}
1007
【题意】
从1~N中不重复的选至少K个数,要求这K个数的乘积不能被除1以外的平方数除尽,求这K个数的和
【题解】
【代码】
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e9+7;
const int maxn = 510;
vector<int>G[maxn];
int dp[maxn][1<<8],n,k;
int p[8] = { 2,3,5,7,11,13,17,19 };
void Mod( int &x ){ x%=mod; }
void check( int x )
{
int s = 0;
for ( int i=0 ; i<8 ; i++ )
if ( x%p[i]==0 )
{
x /= p[i];
s |= 1<<i;
if ( x%p[i]==0 )
return;
}
G[x].push_back(s);
}
int main()
{
for ( int T ; scanf ( "%d" , &T )==1 ; )
{
for ( int Cas=1 ; Cas<=T ; Cas++ )
{
scanf( "%d%d" , &n , &k );
for ( int i=1 ; i<=n ; i++ )
G[i].clear();
for ( int i=1 ; i<=n ; i++ )
check( i );
memset ( dp , 0 , sizeof(dp) );
dp[0][0] = 1;
for ( int i=0 ; i<G[1].size() ; i++ )
for ( int j=k-1 ; j>=0 ; j-- )
for ( int s=0 ; s<(1<<8) ; s++ )
if ( dp[j][s]&&!(s&G[1][i]) )
Mod( dp[j+1][s|G[1][i]]+=dp[j][s] );
for ( int i=2 ; i<=n ; i++ )
if ( G[i].size() )
for ( int j=k-1 ; j>=0 ; j-- )
for ( int s=0 ; s<(1<<8) ; s++ )
if ( dp[j][s] )
for ( int t=0 ; t<G[i].size() ; t++ )
if ( !(s&G[i][t]) )
Mod( dp[j+1][s|G[i][t]]+=dp[j][s] );
int ans = 0;
for ( int i=1 ; i<=k ; i++ )
for ( int j=0 ; j<(1<<8) ; j++ )
ans = ( ans+dp[i][j] )%mod;
printf( "%d\n" , ans );
}
}
return 0;
}
contest-2
1010
【题意】
杨辉三角形第k行有几个奇数
【题解】
奇数个数 = 2^e,(e : k-1 的二进制表示中1的个数)
【代码】
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
#include<list>
#include <iostream>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
const int maxn = 100010;
const int mod = 1e9+7;
int main()
{
ll k;
while(scanf("%lld",&k) != EOF)
{
ll res = 1;
k--;
while(k)
{
if(k & 1)
res = res*2;
k >>= 1;
}
printf("%lld\n",res);
}
return 0;
}
1011
【题意】
有1元硬币:M个,100元:无数
共N天,i-th天,花费 = C[i] 元 ,不开心系数 = W[i],
不开心值 = (找钱数) * (不开心系数),求N天不开心值总和的最小值
【题解】
【代码】
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 100010;
int c[maxn];
int w[maxn];
int main()
{
for ( int T ; scanf ( "%d" , &T )==1 ; )
{
for ( int Cas=1 ; Cas<=T ; Cas++ )
{
int n,m;
scanf ( "%d%d" , &n , &m );
for ( int i=1 ; i<=n ; i++ )
scanf ( "%d" , &c[i] ),c[i] %= 100;
for ( int i=1 ; i<=n ; i++ )
scanf ( "%d" , &w[i] );
LL ans = 0;
priority_queue< LL,vector<LL>,greater<LL> >Q;
for ( int i=1 ; i<=n ; i++ )
{
if ( c[i] )
Q.push( LL(w[i]*(100-c[i])) );
if ( m>=c[i] )
m -= c[i];
else
{
m += 100-c[i];
ans += Q.top();
Q.pop();
}
}
printf ( "%lld\n" , ans );
}
}
return 0;
}
1012
【题意】
【题解】
【代码】
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
#include<list>
#include <iostream>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const LL mod = 1e9+7;
const int maxn = 3e6+5;
const int inf = 0x3f3f3f3f;
bool isprime[110];
int primes[110],len;
void Get_prime()
{
len = 0;
memset ( isprime , true , sizeof(isprime) );
isprime[0] = false;
isprime[1] = false;
for ( int i=2 ; i<=100 ; i++ )
{
if ( isprime[i] )
primes[++len] = i;
for ( int j=1 ; j<=len ; j++ )
{
if ( i*primes[j]>100 )
break;
isprime[i*primes[j]] = false;
if ( i%primes[j]==0 )
break;
}
}
}
int l,r,p,tp;
int a[maxn],b[maxn],s[maxn];
void dfs( int x , int y )
{
if ( x>len||primes[x]>p||primes[x]>r/y )
return;
dfs( x+1 , y );
while ( primes[x]<=r/y )
{
a[++tp] = y*primes[x];
y *= primes[x];
dfs( x+1 , y );
}
}
int main()
{
Get_prime();
for ( int T ; scanf ( "%d" , &T )==1 ; )
{
for ( int Cas=1 ; Cas<=T ; Cas++ )
{
scanf ( "%d%d%d" , &l , &r , &p );
a[tp=1] = 1;
dfs ( 1 , 1 );
sort ( a+1 , a+tp+1 );
for ( int i=1 ; i<=tp ; i++ )
b[i] = inf,s[i] = 0;
b[1] = 0;
for ( int i=2 ; i<=p ; i++ )
{
int tpos = 1;
for ( int j=1 ; j<=tp ; j++ )
{
if ( a[tpos]>a[tp]/i )
break;
while ( tpos<j&&a[tpos]*i<a[j] )
tpos++;
if ( a[tpos]*i==a[j] )
b[j] = min( b[j] , b[tpos]+1 );
if ( b[j]+i<=p )
s[j] = 1;
}
}
int ans = 0;
for ( int i=1 ; i<=tp ; i++ )
if ( s[i]&&a[i]>=l )
ans++;
printf( "%d\n" , ans );
}
}
return 0;
}