1.CRB and Apple
2.CRB and Candies
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5407
解题思路:http://blog.csdn.net/piaocoder/article/details/47985009
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int MOD = 1000000007;
const int N = 1000005;
ll f[N];
int nprime;
int vis[N];
int prime[80000];
void getprime(){
nprime = 0;
memset(vis,0,sizeof(vis));
memset(prime,0,sizeof(prime));
for(int i = 2; i <= N-5; i++){
int t = (N-5)/i;
for(int j = 2; j <= t; j++){
vis[i*j] = 1;
}
}
for(int i = 2; i <= N-5; i++){
if(!vis[i])
prime[nprime++] = i;
}
memset(vis,0,sizeof(vis));
for(int i = 0; i < nprime; i++){
ll a = prime[i];
ll b = a;
for(; a < N; a*=b)
vis[a] = b;
}
}
void init(){
getprime();
f[1] = 1;
for(int i = 2; i <= N-4; i++){
if(vis[i])
f[i] = f[i-1]*vis[i]%MOD;
else
f[i] = f[i-1];
f[i] %= MOD;
}
}
/*
ll extend_gcd(ll a,ll b,ll &x,ll &y){
if(a == 0 && b == 0)
return -1;//无最大公约数
if(b == 0){
x = 1;
y = 0;
return a;
}
ll d = extend_gcd(b,a%b,y,x);
y -= a/b*x;
return d;
}
//*********求逆元素*******************
//ax = 1(mod n)
ll mod_reverse(ll a,ll n)
{
ll x,y;
ll d = extend_gcd(a,n,x,y);
if(d == 1)
return (x%n+n)%n;
else
return -1;
}
*/
ll pow_mod(ll x, int n) {
ll ret = 1;
while (n) {
if (n&1)
ret = ret * x % MOD;
x = x * x % MOD;
n >>= 1;
}
return ret;
}
ll mod_reverse(ll x) {
return pow_mod(x, MOD-2);
}
int main(){
init();
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
//ll ni = mod_reverse(n+1,MOD);
ll ni = mod_reverse(n+1);
printf("%lld\n",f[n+1]*ni%MOD);
}
return 0;
}
3.CRB and Farm
4.CRB and Graph
5.CRB and His Birthday
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5410
解题思路:http://blog.csdn.net/piaocoder/article/details/47977577
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[2005];
int val[1005];
int a[1005],b[1005];
int main(){
int T;
int n,m;
scanf("%d",&T);
while(T--){
scanf("%d%d",&m,&n);
memset(dp,0,sizeof(dp));
for(int i = 1; i <= n; i++)
scanf("%d%d%d",&val[i],&a[i],&b[i]);
for(int i = 1; i <= n; i++)
for(int j = m; j >= val[i]; j--)
dp[j] = max(dp[j],dp[j-val[i]]+a[i]+b[i]);
for(int i = 1; i <= n; i++)
for(int j = val[i]; j <= m; j++)
dp[j] = max(dp[j],dp[j-val[i]]+a[i]);
printf("%d\n",dp[m]);
}
return 0;
}
6.CRB and Puzzle
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5411
解题思路:http://blog.csdn.net/piaocoder/article/details/47983475
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MOD = 2015;
struct matrix//矩阵
{
int m[55][55];
matrix(){
memset(m,0,sizeof(m));
}
};
int n,m;
void debug(matrix a){
for(int i = 1; i <= n+1;i++){
for(int j = 1; j <= n+1; j++){
cout<<a.m[i][j];
}
cout<<endl;
}
}
matrix multi(matrix a, matrix b)
{
matrix tmp;
for(int i = 0; i < 55; ++i)
{
for(int j = 0; j < 55; ++j)
{
for(int k = 0; k < 55; ++k)
tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % MOD;
}
}
return tmp;
}
int fast_mod(matrix ans,matrix base, int m) // 求矩阵 base 的 n 次幂
{
while(m)
{
if(m & 1) //实现 ans *= t; 其中要先把 ans赋值给 tmp,然后用 ans = tmp * t
ans = multi(ans, base);
base = multi(base, base);
m >>= 1;
}
return ans.m[1][n+1];
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
matrix ans,base;
for(int i = 1; i <= n+1; i++)
base.m[i][n + 1] = 1;
int x,xx;
for(int i = 1; i <= n; i++){
scanf("%d",&x);
for(int j = 1; j <= x; j++){
scanf("%d",&xx);
base.m[i][xx] = 1;
}
}
for(int i = 1; i <= n+1; i++)
ans.m[1][i] = 1;
if(m == 1)
printf("%d\n",n+1);
else
printf("%d\n",fast_mod(ans,base,m));
}
return 0;
}
7.CRB and Queries
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5412
解题思路:http://blog.csdn.net/piaocoder/article/details/47979959
AC代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
#define maxn 300007
int tree[maxn];
void add(int p,int n){
for(;p<maxn;p+=p&(-p))
tree[p]+=n;
}
int query(int p){
int ans = 0;
for(;p>0;p-=p&(-p))
ans += tree[p];
return ans;
}
struct Node{
int l,r,k,ty,ans;
};
Node p[maxn];
int id1[maxn],id2[maxn];
void CDQ(int L,int R,int low,int high){
if(R < L) return ;
if(low == high ){
for(;L<=R;L++){
p[id1[L]].ans = low;
}
return ;
}
int mid = (low+high)/2,l=L,r=R,k,u;
for(int i = L;i <= R; i++){
u = id1[i];
if(p[u].ty == 2){
k = query(p[u].r) - query(p[u].l-1);
if(k >= p[u].k) id2[l++] = u;
else {
p[u].k -= k;
id2[r--] = u;
}
}
else if(p[u].k <= mid){
add(p[u].l,p[u].ty);
id2[l++] = u;
}
else id2[r--] = u;
}
for(int i = L; i <= R; i++){
u = id1[i];
if(p[u].ty != 2 && p[u].k <= mid) add(p[u].l,-p[u].ty);
}
for(k=L;k<l;k++)
id1[k] = id2[k];
for(r=R;k<=R;k++)
id1[k] = id2[r--];
CDQ(L,l-1,low,mid);
CDQ(l,R,mid+1,high);
}
int num[maxn];
int main(){
int n,q,t,cnt;
memset(tree,0,sizeof(tree));
while(scanf("%d",&n)!=EOF){
for(cnt=0;cnt<n;cnt++){
scanf("%d",&p[cnt].k);
p[cnt].ty = 1;
p[cnt].l = cnt+1;
num[cnt+1] = p[cnt].k;
}
scanf("%d",&q);
int ty,l,v;
for(int i = 0;i < q; i++,cnt++){
scanf("%d",&p[cnt].ty);
if(p[cnt].ty == 1){
scanf("%d%d",&l,&v);
p[cnt].ty = -1;
p[cnt].k = num[l];
p[cnt].l = l;
cnt++;
num[l] = v;
p[cnt].ty = 1;
p[cnt].k = v;
p[cnt].l = l;
}
else {
scanf("%d%d%d",&p[cnt].l,&p[cnt].r,&p[cnt].k);
}
}
for(int i = 0;i < cnt; i++)
id1[i] = i;
CDQ(0,cnt-1,0,1000000000);
for(int i = 0;i < cnt; i++){
if(p[i].ty == 2) printf("%d\n",p[i].ans);
}
}
return 0;
}
8.CRB and Roads
9.CRB and String
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5414
解题思路:http://blog.csdn.net/piaocoder/article/details/47979099
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 100005;
char s[N],t[N];
int solve(){
int i,j;
int l1 = strlen(s);
int l2 = strlen(t);
for(i = 1; i < l2; i++)
if(t[i] != t[0])
break;//找到t串的第一个不连续的位置
for(j = 0; j < i; j++)//看s的前i个子串是否连续
if(s[j] != t[0])
return 0;
for(; j<l1;){
for(; i<l2; i++){//找到下一个和s相等的地方
if(t[i] == s[j])
break;
}
if(i == l2)
return 0;//如果t找完了还没跳出证明s不是t的子串
i++;
j++;
}
return 1;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%s%s",s,t);
if(solve())
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
10.CRB and Substrings
11.CRB and Tree
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5416
解题思路:http://blog.csdn.net/piaocoder/article/details/47989393
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 100005;
const int maxn = N<<1;
struct node{
int x,w;
};
vector<node> edge[N];
int vis[N];
ll cnt[maxn];
void dfs(int u,int val){
vis[u] = 1;
if(u^1)
cnt[val]++;
int l = edge[u].size();
for(int i = 0; i < l; i++){
node tmp = edge[u][i];
if(!vis[tmp.x]){
dfs(tmp.x,tmp.w^val);
}
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,q;
scanf("%d",&n);
for(int i = 1; i <= n; i++)
edge[i].clear();
int u,v,w;
for(int i = 1; i < n; i++){
scanf("%d%d%d",&u,&v,&w);
edge[u].push_back(node{v,w});
edge[v].push_back(node{u,w});
}
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
dfs(1,0);
scanf("%d",&q);
while(q--){
scanf("%d",&w);
ll ans = 0;
if(w == 0){
ans += n+cnt[0];
for(int i = 0; i < maxn; i++)
ans += cnt[i] * (cnt[i] - 1) / 2;
}
else{
for(int i = 0; i < maxn; i++)
ans += cnt[i] * (cnt[i ^ w]);
ans >>= 1;
ans += cnt[w];
}
printf("%lld\n",ans);
}
}
return 0;
}