牛客算法周周练2

牛客算法周周练2

B Music Problem

牛客算法周周练2_第1张图片
题意:n个物品 01选法 能否凑成3600的整数倍。
思路:dp(写麻烦了,不需要二进制优化其实也可以过,因为抽屉原理当n>=3600时肯定存在答案)
很简单的一个dp,,,但是学到了bitset这种牛逼偷懒 的写法。
dp[i] 表示当前容量是否可行 即dp[j]=(backup[j]|backup[((j-a[i])%3600+3600)%3600]);

dp代码

#pragma GCC optimize(3,"Ofast","inline")  	//G++
#include
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fcout cout<
using namespace std;
//======================================
namespace FastIO {char buf[1 << 21], buf2[1 << 21], a[20], *p1 = buf, *p2 = buf, hh1 = '\n', hh2 = ' ';int p, p3 = -1;
void read() {}
void print() {buf2[p3] = hh1;}
inline int getc() {return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;}
inline void flush() {fwrite(buf2, 1, p3 + 1, stdout), p3 = -1;}
template <typename T, typename... T2>
inline void read(T &x, T2 &... oth) {int f = 0;x = 0;char ch = getc();while (!isdigit(ch)) {if (ch == '-')f = 1;ch = getc();}while (isdigit(ch)) {x = x * 10 + ch - 48;ch = getc();}x = f ? -x : x;read(oth...);}
template <typename T, typename... T2>
inline void print(T x, T2... oth) {if (p3 > 1 << 20)flush();if (x < 0)buf2[++p3] = 45, x = -x;do {a[++p] = x % 10 + 48;} while (x /= 10);do {buf2[++p3] = a[p];} while (--p);buf2[++p3] = hh2;print(oth...);}} // namespace FastIO
using FastIO::print;
using FastIO::read;
typedef long long ll;
typedef pair<int,int> pii;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn = 1e6+5;
//======================================

int mp[maxn];
int dp[10005],backup[10005];
int a[maxn];
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    clock_t c1 = clock();
#endif
//**************************************
    int T;
    read(T);
    while(T--){
        int n;
        read(n);
        for(int i=0,x;i<n;i++){
            read(x);
            mp[x%3600]++;
        }
        mp[3600]=mp[0];
        int cnt=0;
        for(int i=1;i<=3600;i++){
            if(!mp[i]) continue;
            int k=1;
            while(k<=mp[i]){
                a[++cnt]=i*k;
                mp[i]-=k,k*=2;
            }
            if(mp[i]){
                a[++cnt]=mp[i]*i;
                mp[i]=0;
            }
        }   
        n=cnt;
        backup[0]=1;
        for(int i=1;i<=n;i++){
            for(int j=0;j<=3600;j++){
                 dp[j]=(backup[j]|backup[((j-a[i])%3600+3600)%3600]);
            }
            memcpy(backup,dp,sizeof dp);
            if(dp[3600]) break;
        }
        puts((dp[3600])?"YES":"NO");
        for(int i=0;i<=3600;i++) mp[i]=0,dp[i]=0,backup[i]=0;
    }
//**************************************
    FastIO::flush();
#ifndef ONLINE_JUDGE
    cerr << "Time:" << clock() - c1 << "ms" << endl;
#endif
    return 0;
}

bitset代码

#pragma GCC optimize(3,"Ofast","inline")  	//G++
#include
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fcout cout<
using namespace std;
//======================================
namespace FastIO {char buf[1 << 21], buf2[1 << 21], a[20], *p1 = buf, *p2 = buf, hh1 = '\n', hh2 = ' ';int p, p3 = -1;
void read() {}
void print() {buf2[p3] = hh1;}
inline int getc() {return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;}
inline void flush() {fwrite(buf2, 1, p3 + 1, stdout), p3 = -1;}
template <typename T, typename... T2>
inline void read(T &x, T2 &... oth) {int f = 0;x = 0;char ch = getc();while (!isdigit(ch)) {if (ch == '-')f = 1;ch = getc();}while (isdigit(ch)) {x = x * 10 + ch - 48;ch = getc();}x = f ? -x : x;read(oth...);}
template <typename T, typename... T2>
inline void print(T x, T2... oth) {if (p3 > 1 << 20)flush();if (x < 0)buf2[++p3] = 45, x = -x;do {a[++p] = x % 10 + 48;} while (x /= 10);do {buf2[++p3] = a[p];} while (--p);buf2[++p3] = hh2;print(oth...);}} // namespace FastIO
using FastIO::print;
using FastIO::read;
typedef long long ll;
typedef pair<int,int> pii;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn = 1e6+5;
//======================================

int mp[maxn];
int a[maxn];
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    clock_t c1 = clock();
#endif
//**************************************
    int T;
    read(T);
    while(T--){
        int n;
        read(n);
        for(int i=0,x;i<n;i++){
            read(x);
            mp[x%3600]++;
        }
        int cnt=0;
        for(int i=0;i<3600;i++){
            if(!mp[i]) continue;
            int k=1;
            while(k<=mp[i]){
                a[++cnt]=i*k;
                mp[i]-=k,k*=2;
            }
            if(mp[i]){
                a[++cnt]=mp[i]*i;
                mp[i]=0;
            }
        }   
        n=cnt;
        bitset<3600>res,cur;
        for(int i=1;i<=n;i++){
            int x=a[i]%3600;
            cur.reset(),cur[x]=1;
            cur|=(res<<x)|(res>>(3600-x));
            res|=cur;
            if(res[0]) break;
        }
        puts(res[0]?"YES":"NO");
    }
//**************************************
    FastIO::flush();
#ifndef ONLINE_JUDGE
    cerr << "Time:" << clock() - c1 << "ms" << endl;
#endif
    return 0;
}

牛客算法周周练2_第2张图片
题意:树形结构,q次操作。每次增加u和与u距离小于等于2的点权,增加1。在线询问u此时的点权
思路:维护dp数组 ,dp[x][0]表示x对自己的贡献,dp[x][1]表示x对与自已距离为1的儿子的贡献,dp[x][2]表示x对与自已距离为2的孙子的贡献
修改为: dp[fa[x]][1]++; dp[fa[x]][0]++; dp[fa[fa[x]]][0]++; dp[x][1]++; dp[x][2]++;
查询为:dp[x][0]+dp[fa[x]][1]+dp[fa[fa[x]]][2]

#pragma GCC optimize(3,"Ofast","inline")  	//G++
#include
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fcout cout<
using namespace std;
//======================================
namespace FastIO {char buf[1 << 21], buf2[1 << 21], a[20], *p1 = buf, *p2 = buf, hh1 = '\n', hh2 = ' ';int p, p3 = -1;
void read() {}
void print() {buf2[p3] = hh1;}
inline int getc() {return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;}
inline void flush() {fwrite(buf2, 1, p3 + 1, stdout), p3 = -1;}
template <typename T, typename... T2>
inline void read(T &x, T2 &... oth) {int f = 0;x = 0;char ch = getc();while (!isdigit(ch)) {if (ch == '-')f = 1;ch = getc();}while (isdigit(ch)) {x = x * 10 + ch - 48;ch = getc();}x = f ? -x : x;read(oth...);}
template <typename T, typename... T2>
inline void print(T x, T2... oth) {if (p3 > 1 << 20)flush();if (x < 0)buf2[++p3] = 45, x = -x;do {a[++p] = x % 10 + 48;} while (x /= 10);do {buf2[++p3] = a[p];} while (--p);buf2[++p3] = hh2;print(oth...);}} // namespace FastIO
using FastIO::print;
using FastIO::read;
typedef long long ll;
typedef pair<int,int> pii;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn = 1e6+5;
//======================================
vector<int>edge[maxn];
int fa[maxn];
int dp[maxn][3];
void addedge(int x,int y){
    edge[x].push_back(y);
}
void dfs(int u,int father){
    fa[u]=father;
    for(auto v:edge[u]){
        if(v==father) continue;
        dfs(v,u);
    }
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    clock_t c1 = clock();
#endif
//**************************************
    int n,q;
    read(n,q);
    for(int i=1,x,y;i<=n-1;i++){
        read(x,y);
        addedge(x,y),addedge(y,x);
    }
    dfs(1,0);
    while(q--){
        int x;
        read(x);
        dp[fa[x]][1]++;
        dp[fa[x]][0]++;
        dp[fa[fa[x]]][0]++;
        dp[x][1]++;
        dp[x][2]++;
        print(dp[x][0]+dp[fa[x]][1]+dp[fa[fa[x]]][2]);
    }
//**************************************
    FastIO::flush();
#ifndef ONLINE_JUDGE
    cerr << "Time:" << clock() - c1 << "ms" << endl;
#endif
    return 0;
}

你可能感兴趣的:(牛客补题)