日常訓練 20170602 B君的教育

題意簡述:有一個性質是設 p=1+i ,對於每個高斯整數 x+yi ,我們都可以找到一個非負整數集合 S 滿足 iSpi=n ,在輸入 xy 的情況下,輸出 S
對於一個複數(Complex Number),如果它的實部和虛部都是整數,我們稱之爲高斯整數。
很多大佬們都想到了可以做類似二進制拆分,就用了短除法,複雜度 O(logn) ,然而我這麼水,只會暴搜,但是我發現了這些冪次之間值相差很大,從大到小選只要選錯一個後面就再也補不回來了(這不就是進制嘛,我真是智障),然後暴力就加了一個前綴和的優化,所以複雜度也是 O(logn)

#include<bits/stdc++.h>
typedef long long ll;
ll x,y;
namespace subtask3{
    const int N = 126;
    struct CN{
        ll r, i;
        CN(){}
        CN(ll _r, ll _i):
            r(_r),i(_i){}
    }p[N];
    CN operator * (const CN &a, const CN &b) {
        return CN(a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r);
    }
    ll sx[N], _sx[N], sy[N], _sy[N];
    int a[N + 1];
    bool find;
    void dfs(int dep, ll x, ll y) {
        if (dep < 0) {
            if (!x && !y) {
                find = 1;
                for (int i=a[0]; i > 0; i--)
                    printf("%d\n",a[i]);
            }
            return;
        }
        if (find || x + sx[dep] < 0 || x + _sx[dep] > 0 
                 || y + sy[dep] < 0 || y + _sy[dep] > 0) {
            //printf("find=%d dep=%d x=%lld y=%lld\n", find, dep, x, y);     
            return;
        }
        dfs(dep - 1, x, y);
        a[++a[0]] = dep;
        dfs(dep - 1, x + p[dep].r, y + p[dep].i);
        a[0]--;
    }
    int main(){
        p[0] = CN(1,0);
        sx[0] = 1, _sx[0] = 0;
        sy[0] = 0, _sy[0] = 0;
        for (int i=1; i<N; i++) {
            p[i] = p[i - 1] * CN(-1, 1);
            sx[i] = sx[i - 1], _sx[i] = _sx[i - 1];
            sy[i] = sy[i - 1], _sy[i] = _sy[i - 1];
            if (p[i].r > 0)
                sx[i] += p[i].r;
            else
                _sx[i] += p[i].r;
            if (p[i].i > 0)
                sy[i] += p[i].i;
            else
                _sy[i] += p[i].i;
        }
        dfs(N - 1, -x, -y);
        return 0;
    }
}
int main(){
    scanf("%lld%lld",&x,&y);
    subtask3::main();
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章