SRM 621 div2 1000

给一组数, 求异或运算下组成数组的基的元素个数, 1<=n<=50
题解中提到了线性无关, 空间的基QAQ

观察1
..:
所谓``异或运算下''就是所有元素由基中元素的异或产生
注意异或属于模2运算, 即对某数异或的结果只有异或奇数次和异或偶数次两种

举例
..:
若基是{1, 2}, 那么可产生所有元素是{1, 2, 3}
..:
若给出的是{1, 2, 3, 4, 5}
转为01表示
0001
0010
0011
0100
0101
立即使用线性代数中办法
设i从第一行开始, 对i行逐位扫描, i行后的每一行如果同位为1, 就异或, 1<=i<n
..:
其实就是化简矩阵求出线性无关向量的办法, 只不过这里是异或且只异或一次
..:
逐位扫描可以用__builtin_ffs, 也可以用__builtin__clz, 扫描方向不同罢了~~

写出代码
..:
#include <bits/stdc++.h>
using namespace std;

int n, r;
inline void dodo(vector<int>& c, int x) {
    for (int i=x+1; i<n; i++) if (c[i]&(1<<__builtin_ffs(c[x])-1))
        c[i]^=c[x];
}
class MixingColors {
public:
    int minColors(vector <int> c) {
        n=c.size();
        for (int i=0; i<n; i++) if (c[i]) dodo(c, i);
        for (int i=0; i<n; i++) if (c[i]) r++;
        return r;
    }
};

SRM 622 div2 1000

给一有重复数字集合, 求满足以下性质的所有子集(可全集不可空集):
所有数字和大于数字积, 1<=n<=1000

观察1
..:
若xy<x+y则xy-x-y<0
即xy-x-y+1<1即(x-1)(y-1)<1, 可见x, y中至少有1
..:
若xyz<x+y+z则xyz-x-y-z<0
即xyz-xy-yz-zx+x+y+z-1+xy+yz+xz-2x-2y-2z+1<0
也(x-1)(y-1)(z-1)+(x-1)(y-1)+(y-1)(z-1)+(x-1)(z-1)<2, 可见x, y, z中至少有1
..:
猜测推广至n

观察2
..:
根据观察1可见复杂度并不是n的全子集, 至于是什么不会证QAQ:..

所以
..:
先求出1的个数, 然后枚举非1元素的子集, 看是否满足要求
排序后可以剪枝, 就是当发现已经不满足就没有必要继续枚举了

写出代码
..:
#include <bits/stdc++.h>
using namespace std;

int n, o, r, t;
int v[1001];
int m[1001];
int s[1001];
inline void dodo(int x, int c) {
    int a=0, b=1;
    for (int i=0; i<c; i++) a+=s[i], b*=s[i];
    if (b-a<=o)
        r+=o-(b-a);
    else
        return;
    for (int i=x; i<t; i++) if (v[i]) {
        s[c]=m[i];
        v[i]--;
        dodo(i, c+1);
        v[i]++;
    }
}
inline void push(int x) {
    for (int i=0; i<t; i++) if (m[i]==x) {
        v[i]++;
        return;
    }
    m[t]=x;
    v[t]++;
    t++;
}
class Subsets {
public:
    int findSubset(vector<int> N) {
        n=N.size();
        sort(N.begin(), N.end());
        for ( ; N[o]==1 && o<n; o++) ;
        for (int i=o; i<n; i++)
            push(N[i]);
        dodo(0, 0);
        printf("%d %d\n", n, o);
        return r;
    }
};

DARK SOULS: 永久保持人性(仅外表)

活尸状态简直丑到爆:..

char jmp=0xeb;
DWORD off=0x98610b;
DWORD old;
DWORD awe=addr+off;

VirtualProtect((void*)(awe+1), 1, PAGE_EXECUTE_READWRITE, &old);
WriteProcessMemory(pro, (void*)(awe), &jmp, 1, NULL);
VirtualProtect((void*)(awe+1), 1, old, &old);

1个字节的事情..指令地址就是DATA.exe+0x0098610b喽

内存管理: Buddy system

/* Buddy system algorithm */

/* Written by Kai Wang */
using namespace std;

#include <cstring>
#include <cmath>
#include <sstream>
#include <iostream>
#include <vector>
#include <utility>

#define FOR(i, a, b) for (int i=(a); i<=(b); i++)
#define REP(i, a)       for (int i=0; i<(a); i++)
#define all(a)             (a).begin(), (a).end()
#define sz(a)                   (int)((a).size())
#define mp                              make_pair
#define y                                  second
#define x                                   first

#define MEMO_SIZE                              21

int main() {

    /* first of pair is rank of block size, 
       second is it's process */
    vector<pair<int, char> > memo;

    /* 2 MB, '*' indicates empty block  */
    memo.insert(memo.begin(), mp(MEMO_SIZE, '*'));

    string cmd;
    while (cin>>cmd) {
        cout<<cmd<<" ";
        char wh=cmd[0]; cin>>cmd;
        cout<<cmd<<endl;
        char op=cmd[0];
        stringstream ss(cmd.substr(1));
        int size; ss>>size;
        int r=floor(log2(size*1024))+1;
        typeof(memo.begin()) it;
        if (op=='+') {
            it=find(all(memo), mp(r, '*'));
            /* found an empty block of rank r */
            if (it!=memo.end()) {
                it->y=wh;
                goto next;
            }
            /* divide the first available larger block */
            FOR(i, r+1, MEMO_SIZE) {
                it=find(all(memo), mp(i, '*'));
                if (it==memo.end())
                    continue;
                int time=i-r;
                while (time--) {
                    it=memo.erase(it);
                    it=memo.insert(it, mp(i-1, '*'));
                    it=memo.insert(it, mp(i-1, '*'));
                    i--;
                }
                it->y=wh;
                break;
            }
        } else {
            it=find(all(memo), mp(r, wh));
            it->y='*';
            /* try merge neighbour block, left first, than right */
            while (it->y=='*') {
                int id=it-memo.begin();
                if (id>=1 && memo[id-1].x==r && memo[id-1].y=='*') {
                    it--;
                    it=memo.erase(it);
                    it=memo.erase(it);
                    it=memo.insert(it, mp(r+1, '*'));
                    r++;
                    goto next_try;
                } else if (id<MEMO_SIZE && memo[id+1].x==r &&
                           memo[id+1].y=='*') {
                    it=memo.erase(it);
                    it=memo.erase(it);
                    it=memo.insert(it, mp(r+1, '*'));
                    r++;
                    goto next_try;
                }
                break;
next_try:;
            }
        }
next:
        REP(i, sz(memo)) {
            cout<<(int)pow(2, memo[i].x)/1024<<memo[i].y;
            if (i==sz(memo)-1)
                cout<<endl;
            else
                cout<<"  ";
        }
        cout<<endl;
    }
    return 0;
}

Codeforces 202 DIV2 C

简单的二分查找:..
#include <stdio.h>
#include <algorithm>
using namespace std;
/* Codeforces */
/*****************************************************************************/
int main(void) {
    int n, a;
    long long m=0, s=0;
    scanf("%d", &n);
    for (int i=0; i<n; i++) {
        scanf("%d", &a);
        s+=a;
        m=max(m, (long long)a);
    }
    long long l=0, h=2e9+1, ans;
    while (l<=h) {
        long long mid=(l+h)/2;
        if (mid*(n-1)>=s) {
            h=mid-1;
            ans=mid;
        } else
            l=mid+1;
    }
    printf("%I64d\n", max(m, ans));
    return 0;
}
/*****************************************************************************/

Codeforces 202 DIV2 B

又是简单贪心:..
#include <stdio.h>
#include <climits>
#include <algorithm>
using namespace std;
/* Codeforces */
/*****************************************************************************/
int main(void) {
    int v, d[10], n, m=INT_MAX;
    scanf("%d", &v);
    for (int i=1; i<=9; i++) {
        scanf("%d", &d[i]);
        m=min(m, d[i]);
    }
    if (m>v) puts("-1");
    else {
        n=v/m;
        while (n--)
            for (int i=9; i>0; i--)
                if (v>=d[i]&&(v-d[i])/m==n) {
                    printf("%d", i);
                    v-=d[i];
                    break;
                }
        puts("");
    }
    return 0;
}
/*****************************************************************************/

Codeforces 202 DIV2 A

简单贪心:..
#include <stdio.h>
using namespace std;
/* Codeforces */
/*****************************************************************************/
int main(void) {
    int n, r, t[2]={};
    scanf("%d", &n);
    for (int i=0; i<n; i++) {
        scanf("%d", &r);
        if (r==25) {
            t[0]++;
        } else if (r==50) {
            if (t[0]>0) {
                t[0]--; t[1]++;
            } else {
                puts("NO"); return 0;
            }
        } else {
            if (t[1]>0) {
                t[1]--;
                if (t[0]>0) {
                    t[0]--;
                } else {
                    puts("NO"); return 0;
                }
            } else if (t[0]>=3) {
                t[0]-=3;
            } else {
                puts("NO"); return 0;
            }
        }
    }
    puts("YES");
    return 0;
}
/*****************************************************************************/