月度归档:2018年08月

洛谷 P1290 欧几里德的游戏

又是一道博弈论:题解:
https://www.luogu.org/blog/DJCreeper/p1290-ti-xie

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<iostream>
#include<algorithm>
using namespace std;
void Stan(int,int);
void Ollie(int,int);
void Stan(int i,int j){
    if(i==j||i/j>=2)cout<<"Stan wins"<<endl;
    else Ollie(max(i-j,j),min(i-j,j));
}
void Ollie(int i,int j){
    if(i==j||i/j>=2)cout<<"Ollie wins"<<endl;
        else Stan(max(i-j,j),min(i-j,j));
}
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        int v1,v2;
        cin>>v1>>v2;
        if(v1<v2)swap(v1,v2);
        Stan(v1,v2);
    }
}

洛谷 P1441 砝码称重

先写了个两层搜索,后来又参考题解改了个搜索+动态规划。
题解:https://www.luogu.org/blog/yeyangrui/solution-p1441
60分搜索:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include<iostream>
#include<algorithm>
#include<cstring>
#define NINF 0x80000000
using namespace std;
int n,m;
bool mass[2005];
int weight[25];
bool visited[25];
void dfs(int pos,int num){
    if(pos==n+1)return;
    if(visited[pos]){
        dfs(pos+1,num);
        return;
    }
    mass[num+weight[pos]]=true;
    dfs(pos+1,num+weight[pos]);
    mass[num]=true;
    dfs(pos+1,num);
}
int getMassCounts(){
    memset(mass,false,sizeof(mass));
    dfs(1,0);
    int cnter=0;
    for(int i=1;i<=n*100;i++)if(mass[i])cnter++;
    return cnter;
}
int genCombination(int pos,int num){
    if(num==m)return getMassCounts();
    if(pos>n)return NINF;
    int maxC=NINF;
    visited[pos]=true;
    maxC=max(maxC,genCombination(pos+1,num+1));
    visited[pos]=false;
    maxC=max(maxC,genCombination(pos+1,num));
    return maxC;
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>weight[i];
    cout<<genCombination(1,0);
}

100分动规:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<iostream>
#include<algorithm>
#include<cstring>
#define NINF 0x80000000
using namespace std;
int n,m;
int f[2005];
int weight[25];
bool visited[25];
int getMassCounts(){
    memset(f,0,sizeof(f));
    f[0]=1;
    for(int i=1;i<=n;i++){
        if(visited[i])continue;
        for(int j=2000;j>=0;j--){
            if(j+weight[i]<=2000&&f[j]!=0)f[j+weight[i]]=1;
        }
    }
    int cnter=0;
    for(int i=1;i<=2000;i++)if(f[i])cnter++;
    return cnter;
}
int genCombination(int pos,int num){
    if(num==m)return getMassCounts();
    if(pos>n)return NINF;
    int maxC=NINF;
    visited[pos]=true;
    maxC=max(maxC,genCombination(pos+1,num+1));
    visited[pos]=false;
    maxC=max(maxC,genCombination(pos+1,num));
    return maxC;
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>weight[i];
    cout<<genCombination(1,0);
}

洛谷 P2320 [HNOI2006]鬼谷子的钱袋

想不出来:参考题解:
https://www.luogu.org/blog/user50514/solution-p2320
https://www.luogu.org/blog/user26625/solution-p2320

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll ans,n,z[70];
int main(){
    cin>>n;
    while(n){
        z[++ans]=(n+1)/2;
        n/=2;
    }
    sort(z+1,z+ans+1);
    cout<<ans<<endl;
    for(int i=1;i<=ans;i++)cout<<z[i]<<" ";
}

洛谷 P1113 杂务

这题本来就是个拓扑排序,搞了半天竟然搞不出来,想了半天。。
一开始的想法是:搞拓扑排序,一轮一轮的扫描,每一轮出一个最大时间,把最大时间相加就好了,后来发现全WA,为什么呢?因为同一轮里出来的任务其实有可能是不互相依赖的。比如任务1时间需要10;任务2时间需要5;任务3需要在任务1之后,任务4需要在任务2之后。如果一轮一轮的扫描,那么必须10秒之后同时开始做任务3/4。而实际情况则应该是任务2,5个时间作完之后就可以做任务4了。根据失误我又想着反向建图,用DFS递归解决,对每个结点(及其之前节点)找其最大的所用时间,写出来AC了(对于本题,杂务 k(k>1)的准备工作只可能在杂务 1 至 k-1 中,如果没有这个要求,反向建图就很好)。但是其实我想多了。直接一开始的拓扑排序,顺着推就可以了。
DFS版:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int n,times[10005],inDegree[10005],f[10005];
vector<int> edges[10005];
vector<int> curTasks;
int dfs(int node){
    if(f[node]!=0)return f[node];
    if(edges[node].size()==0)return f[node]=times[node];
    int maxT=0;
    for(int i=0;i<edges[node].size();i++){
        maxT=max(maxT,dfs(edges[node][i]));
    }
    return f[node]=maxT+times[node];
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++){
        int v;
        cin>>v>>times[i];
        while(1){
            cin>>v;
            if(v==0)break;
            edges[i].push_back(v);
            inDegree[v]++;
        }
    }
    int maxTime=0;
    for(int i=1;i<=n;i++){
        if(inDegree[i]==0)maxTime=max(maxTime,dfs(i));
    }
    cout<<maxTime;
}

正常版:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int n,times[10005],inDegree[10005],allTimes[10005];
vector<int> edges[10005];
int sumTime=0;
int main(){
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++){
        int v;
        cin>>v>>times[i];
        while(1){
            cin>>v;
            if(v==0)break;
            edges[v].push_back(i);
            inDegree[i]++;
        }
    }
    int maxT=0;
    for(int i=1;i<=n;i++)if(inDegree[i]==0){
        allTimes[i]+=times[i];
        for(int j=0;j<edges[i].size();j++){
            allTimes[edges[i][j]]=max(allTimes[edges[i][j]],allTimes[i]);
            inDegree[edges[i][j]]--;
        }
        inDegree[i]--;
        maxT=max(maxT,allTimes[i]);
    }
    cout<<maxT;
}

洛谷 P1066 2^k进制数

50分的一个搜索写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int result[205];
int pow2[10]={1,2,4,8,16,32,64,128,256,512};
int k,w;
inline void percolate(){
    for(int i=1;i<=203&&result[i]>10000;i++){
        result[i+1]+=result[i]/10000;
        result[i]%=10000;
    }
}
inline void dfs(int pos,int num){
    if(num==0)return;
    if((w%k==0?w/k:w/k+1)<pos)return;
    if(w%k!=0&&(w/k+1)==pos)num=min(pow2[w%k]-1,num);
    for(int i=1;i<=num;i++)dfs(pos+1,i-1);
    if(pos!=1){
        result[1]+=num;
        percolate();
    }
}
int main(){
    cin>>k>>w;
    dfs(1,pow2[k]-1);
    int flag=0;
    for(int i=204;i>0;i--){
        if(result[i])flag++;
        if(result[i]==0){if(flag)cout<<"0000";}
        else printf((flag==1?"%d":"%04d"),result[i]);
    }
}

100分写法:
参考题解:https://www.luogu.org/blog/user50852/solution-p1066

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include<iostream>
#include<string>
#include<algorithm>
#define PINF 0x7fffffff
using namespace std;
struct bigInt { //For Non-negative Numbers
    // You must include header **iostream** and **string** before using this class!
private:
    string v;
    static string & bIsort(string & v) { //each char has reduced '0'
        for (int i = 0; i < v.length(); i++) {
            if (v[i] > 9) {
                if (i == v.length() - 1)v.append(1, v[i] / 10);
                else v[i + 1] += v[i] / 10;
                v[i] %= 10;
            }
        }
        return v;
    }
    static string lng2str(long long v) {
        string s = "";
        while (v) {
            s.append(1, v % 10 + '0');
            v /= 10;
        }
        reverse(s.begin(), s.end());
        return s;
    }
    static string& trimPre0(string& v3) {
        while (v3.length() != 0 && (*v3.begin()) == '0')v3.erase(v3.begin());
        if (v3.length() == 0)v3 = "0";
        return v3;
    }
public:
    bigInt() {
        v = "0";
    }
    bigInt(long long n) {
        v = lng2str(n);
    }
    bigInt(string s) {
        v = s;
    }
    bigInt& operator = (const bigInt & bI) {
        this->v = bI.v;
        return *this;
    }
    bigInt operator + (bigInt bI2) const {
        string s1 = v, s2 = bI2.v;
        if (s1.length() > s2.length())swap(s1, s2);
        reverse(s1.begin(), s1.end());
        reverse(s2.begin(), s2.end());
        int s1len = s1.length(), s2len = s2.length();
        for (int i = 0; i < s1len; i++)s2[i] += s1[i] - '0';
        for (int i = 0; i < s2len - 1; i++)if (s2[i] > '9') {
            s2[i + 1] += (s2[i] - '0') / 10;
            s2[i] = '0' + (s2[i] - '0') % 10;
        }
        if (s2[s2len - 1] > '9') {
            s2.append(1, '0' + (s2[s2len - 1] - '0') / 10);
            s2[s2len - 1] = '0' + (s2[s2len - 1] - '0') % 10;
        }
        reverse(s2.begin(),s2.end());
        return bigInt(s2);
    }
    bigInt operator - (bigInt bI2) const {
        string s1, s2;
        if ((*this) < bI2) {
            s1 = v; s2 = bI2.v;
        }
        else {
            s1 = bI2.v; s2 = v;
        }
        reverse(s1.begin(), s1.end());
        reverse(s2.begin(), s2.end());
        int s1len = s1.length(), s2len = s2.length();
        for (int i = 0; i<s1len; i++)s2[i] -= s1[i] - '0';
        for (int i = 0; i<s2len - 1; i++)if (s2[i]<'0') {
                s2[i + 1] -= 1;
                s2[i] += 10;
        }
        if (s2[s2len - 1] == '0')s2.erase(s2.end() - 1);
        reverse(s2.begin(), s2.end());
        return bigInt(trimPre0(s2));
    }
    bigInt operator * (bigInt bI2) const {
        string v1 = v, v2 = bI2.v;
        if (v2.length() > v1.length())swap(v1, v2);
        reverse(v1.begin(), v1.end());
        reverse(v2.begin(), v2.end());
        string v3 = "";
        for (int i = 0; i < v1.length(); i++)v1[i] -= '0';
        for (int i = 0; i < v2.length(); i++)v2[i] -= '0';
        v3.resize(v1.length() + v2.length(), 0);
        for (int i = 0; i < v2.length(); i++) {
            for (int j = 0; j < v1.length(); j++) {
                v3[i + j] += v2[i] * v1[j];
            }
            bIsort(v3);
        }
        for (int i = 0; i < v3.length(); i++)v3[i] += '0';
        reverse(v3.begin(), v3.end());
        trimPre0(v3);
        return bigInt(v3);
    }
    bigInt operator / (long long bI2) const {
        string v1 = v;
        for (int i = 0; i < v1.length(); i++)v1[i] -= '0';
        long long v2 = bI2;
        string v3 = "";
        long long div = 0;
        for (int i = 0; i < v1.length(); i++) {
            div *= 10;
            div += v1[i];
            if (div < v2) {
                v3.append(1, '0');
                continue;
            }
            v3.append(lng2str(div / v2));
            div %= v2;
        }
        return bigInt(trimPre0(v3));
    }
    bool operator < (bigInt bI2) const {
        if (v.length() != bI2.v.length())return v.length() < bI2.v.length();
        for (int i = 0; i < v.length(); i++) {
            if (v[i] != bI2.v[i])return v[i] < bI2.v[i];
        }
        return false;
    }
    friend istream& operator >> (istream& in, bigInt& bI) {
        in >> bI.v;
        return in;
    }
    friend ostream& operator << (ostream& out, bigInt& bI) {
        out << bI.v;
        return out;
    }
};

bigInt ans=0,f[520][520];

int main(){
    int k,w;
    cin>>k>>w;
    int maxLen=w/k;
    if(w%k!=0)maxLen++;
    int radix=1<<k;
    maxLen=min(maxLen,radix-1);
    for(int i=1;i<=radix-1;i++)f[1][i]=1;
    for(int i=2;i<=maxLen;i++){
        int l;
        if(w%k==0)l=PINF;
        else if(i==maxLen)l=(1<<(w%k))-1;
        else l=PINF;
        for(int j=radix-i;j>0;j--){
            f[i][j]=f[i][j+1]+f[i-1][j+1];
            if(j<=l)ans=ans+f[i][j];
        }
    }
    cout<<ans;
}

高精度板子

留做备用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
struct bigInt { //For Non-negative Numbers
    // You must include header **iostream**,**algorithm** and **string** before using this class!
private:
    string v;
    static string & bIsort(string & v) { //each char has reduced '0'
        for (int i = 0; i < v.length(); i++) {
            if (v[i] > 9) {
                if (i == v.length() - 1)v.append(1, v[i] / 10);
                else v[i + 1] += v[i] / 10;
                v[i] %= 10;
            }
        }
        return v;
    }
    static string lng2str(long long v) {
        string s = "";
        while (v) {
            s.append(1, v % 10 + '0');
            v /= 10;
        }
        reverse(s.begin(), s.end());
        return s;
    }
    static string& trimPre0(string& v3) {
        while (v3.length() != 0 && (*v3.begin()) == '0')v3.erase(v3.begin());
        if (v3.length() == 0)v3 = "0";
        return v3;
    }
public:
    bigInt() {
        v = "0";
    }
    bigInt(long long n) {
        v = lng2str(n);
    }
    bigInt(string s) {
        v = s;
    }
    bigInt& operator = (const bigInt & bI) {
        this->v = bI.v;
        return *this;
    }
    bigInt operator + (bigInt bI2) const {
        string s1 = v, s2 = bI2.v;
        if (s1.length() > s2.length())swap(s1, s2);
        reverse(s1.begin(), s1.end());
        reverse(s2.begin(), s2.end());
        int s1len = s1.length(), s2len = s2.length();
        for (int i = 0; i < s1len; i++)s2[i] += s1[i] - '0';
        for (int i = 0; i < s2len - 1; i++)if (s2[i] > '9') {
            s2[i + 1] += (s2[i] - '0') / 10;
            s2[i] = '0' + (s2[i] - '0') % 10;
        }
        if (s2[s2len - 1] > '9') {
            s2.append(1, '0' + (s2[s2len - 1] - '0') / 10);
            s2[s2len - 1] = '0' + (s2[s2len - 1] - '0') % 10;
        }
        reverse(s2.begin(),s2.end());
        return bigInt(s2);
    }
    bigInt operator - (bigInt bI2) const {
        string s1, s2;
        if ((*this) < bI2) {
            s1 = v; s2 = bI2.v;
        }
        else {
            s1 = bI2.v; s2 = v;
        }
        reverse(s1.begin(), s1.end());
        reverse(s2.begin(), s2.end());
        int s1len = s1.length(), s2len = s2.length();
        for (int i = 0; i<s1len; i++)s2[i] -= s1[i] - '0';
        for (int i = 0; i<s2len - 1; i++)if (s2[i]<'0') {
                s2[i + 1] -= 1;
                s2[i] += 10;
        }
        if (s2[s2len - 1] == '0')s2.erase(s2.end() - 1);
        reverse(s2.begin(), s2.end());
        return bigInt(trimPre0(s2));
    }
    bigInt operator * (bigInt bI2) const {
        string v1 = v, v2 = bI2.v;
        if (v2.length() > v1.length())swap(v1, v2);
        reverse(v1.begin(), v1.end());
        reverse(v2.begin(), v2.end());
        string v3 = "";
        for (int i = 0; i < v1.length(); i++)v1[i] -= '0';
        for (int i = 0; i < v2.length(); i++)v2[i] -= '0';
        v3.resize(v1.length() + v2.length(), 0);
        for (int i = 0; i < v2.length(); i++) {
            for (int j = 0; j < v1.length(); j++) {
                v3[i + j] += v2[i] * v1[j];
            }
            bIsort(v3);
        }
        for (int i = 0; i < v3.length(); i++)v3[i] += '0';
        reverse(v3.begin(), v3.end());
        trimPre0(v3);
        return bigInt(v3);
    }
    bigInt operator / (long long bI2) const {
        string v1 = v;
        for (int i = 0; i < v1.length(); i++)v1[i] -= '0';
        long long v2 = bI2;
        string v3 = "";
        long long div = 0;
        for (int i = 0; i < v1.length(); i++) {
            div *= 10;
            div += v1[i];
            if (div < v2) {
                v3.append(1, '0');
                continue;
            }
            v3.append(lng2str(div / v2));
            div %= v2;
        }
        return bigInt(trimPre0(v3));
    }
    bool operator < (bigInt bI2) const {
        if (v.length() != bI2.v.length())return v.length() < bI2.v.length();
        for (int i = 0; i < v.length(); i++) {
            if (v[i] != bI2.v[i])return v[i] < bI2.v[i];
        }
        return false;
    }
    friend istream& operator >> (istream& in, bigInt& bI) {
        in >> bI.v;
        return in;
    }
    friend ostream& operator << (ostream& out, bigInt& bI) {
        out << bI.v;
        return out;
    }
};

Update 20180924:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
class bigInt {
/*
This class is capable of calculating big non-negative numbers.
You must include header files **iostream**,**algorithm** and **string** before using this class!
*/

private:
    string v;
    static string & bIsort(string & v) { //each char has reduced '0'
        for (int i = 0; i < v.length(); i++) {
            if (v[i] > 9) {
                if (i == v.length() - 1)v.append(1, v[i] / 10);
                else v[i + 1] += v[i] / 10;
                v[i] %= 10;
            }
        }
        return v;
    }
    static string lng2str(unsigned long long v) {
        string s = "";
        while (v) {
            s.append(1, v % 10 + '0');
            v /= 10;
        }
        reverse(s.begin(), s.end());
        return s;
    }
    static string & trimPre0(string & v3) {
        while (v3.length() != 0 && (*v3.begin()) == '0')v3.erase(v3.begin());
        if (v3.length() == 0)v3 = "0";
        return v3;
    }
public:
    bigInt() {
        v = "0";
    }
    bigInt(long long n) {
        v = lng2str(n);
    }
    bigInt(string s) {
        v = s;
    }
    bigInt & operator = (const bigInt & bI) {
        this->v = bI.v;
        return *this;
    }
    bigInt operator + (const bigInt & bI2) const {
        string s1 = v, s2 = bI2.v;
        if (s1.length() > s2.length())swap(s1, s2);
        reverse(s1.begin(), s1.end());
        reverse(s2.begin(), s2.end());
        int s1len = s1.length(), s2len = s2.length();
        for (int i = 0; i < s1len; i++)s2[i] += s1[i] - '0';
        for (int i = 0; i < s2len - 1; i++)if (s2[i] > '9') {
            s2[i + 1] += (s2[i] - '0') / 10;
            s2[i] = '0' + (s2[i] - '0') % 10;
        }
        if (s2[s2len - 1] > '9') {
            s2.append(1, '0' + (s2[s2len - 1] - '0') / 10);
            s2[s2len - 1] = '0' + (s2[s2len - 1] - '0') % 10;
        }
        reverse(s2.begin(), s2.end());
        return bigInt(s2);
    }
    bigInt operator - (const bigInt & bI2) const {
        string s1, s2;
        if ((*this) < bI2) {
            s1 = v; s2 = bI2.v;
        }
        else {
            s1 = bI2.v; s2 = v;
        }
        reverse(s1.begin(), s1.end());
        reverse(s2.begin(), s2.end());
        int s1len = s1.length(), s2len = s2.length();
        for (int i = 0; i<s1len; i++)s2[i] -= s1[i] - '0';
        for (int i = 0; i<s2len - 1; i++)if (s2[i]<'0') {
            s2[i + 1] -= 1;
            s2[i] += 10;
        }
        if (s2[s2len - 1] == '0')s2.erase(s2.end() - 1);
        reverse(s2.begin(), s2.end());
        return bigInt(trimPre0(s2));
    }
    bigInt operator * (const bigInt & bI2) const {
        string v1 = v, v2 = bI2.v;
        if (v2.length() > v1.length())swap(v1, v2);
        reverse(v1.begin(), v1.end());
        reverse(v2.begin(), v2.end());
        string v3 = "";
        for (int i = 0; i < v1.length(); i++)v1[i] -= '0';
        for (int i = 0; i < v2.length(); i++)v2[i] -= '0';
        v3.resize(v1.length() + v2.length(), 0);
        for (int i = 0; i < v2.length(); i++) {
            for (int j = 0; j < v1.length(); j++) {
                v3[i + j] += v2[i] * v1[j];
            }
            bIsort(v3);
        }
        for (int i = 0; i < v3.length(); i++)v3[i] += '0';
        reverse(v3.begin(), v3.end());
        trimPre0(v3);
        return bigInt(v3);
    }
    bigInt operator / (const unsigned long long & bI2) const {
        string v1 = v;
        for (int i = 0; i < v1.length(); i++)v1[i] -= '0';
        long long v2 = bI2;
        string v3 = "";
        long long div = 0;
        for (int i = 0; i < v1.length(); i++) {
            div *= 10;
            div += v1[i];
            if (div < v2) {
                v3.append(1, '0');
                continue;
            }
            v3.append(lng2str(div / v2));
            div %= v2;
        }
        return bigInt(trimPre0(v3));
    }
    unsigned long long operator % (const unsigned long long & bI2) const {
        string v1 = v;
        for (int i = 0; i < v1.length(); i++)v1[i] -= '0';
        unsigned long long v2 = bI2;
        unsigned long long div = 0;
        for (int i = 0; i < v1.length(); i++) {
            div *= 10;
            div += v1[i];
            if (div < v2)continue;
            div %= v2;
        }
        return div % v2;
    }
    bigInt & operator += (const bigInt & bI2) {
        *this = *this + bI2;
        return *this;
    }
    bigInt & operator -= (const bigInt & bI2) {
        *this = *this - bI2;
        return *this;
    }
    bigInt & operator *= (const bigInt & bI2) {
        *this = *this * bI2;
        return *this;
    }
    bool operator < (const bigInt & bI2) const {
        if (v.length() != bI2.v.length())return v.length() < bI2.v.length();
        for (int i = 0; i < v.length(); i++) {
            if (v[i] != bI2.v[i])return v[i] < bI2.v[i];
        }
        return false;
    }
    bool operator == (const bigInt & bI2) const {
        return v == bI2.v;
    }
    friend istream& operator >> (istream& in, bigInt & bI) {
        in >> bI.v;
        return in;
    }
    friend ostream& operator << (ostream& out, bigInt & bI) {
        out << bI.v;
        return out;
    }
};

20181121更新:(高精加法、高精减法、高精乘法、高精除单精(商、模)、高精除高精(商、模)全部测试通过,Final Version)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
class bigInt {
    /*
    This class is capable of calculating big non-negative numbers of any length.
    You must include header files **iostream**,**algorithm**,**cstdio** and **vector** before using this class!
    */

    typedef vector<int> Container;
private:
    Container v; //Every Digit is stored in this vector in the reverse order
    static Container & bIsort(Container & v) {
        for (int i = 0; i < (int)v.size(); i++) {
            if (v[i] > 9) {
                if (i == (int)v.size() - 1)v.push_back(v[i] / 10);
                else v[i + 1] += v[i] / 10;
                v[i] %= 10;
            }
        }
        return v;
    }
    static Container lng2vec(unsigned long long v) {
        Container c;
        while (v) {
            c.push_back(v % 10);
            v /= 10;
        }
        return c;
    }
    static Container & trimPre0(Container & v) {
        int cnt = 0;
        int i = v.size() - 1;
        while (i >= 0 && v[i] == 0)i--, cnt++;
        v.resize(v.size() - cnt);
        if (v.size() == 0)v.push_back(0);
        return v;
    }
    static Container easyDiv(bigInt & bI1, const bigInt & bI2) {
        unsigned long long cnt = 0;
        while (bI1 >= bI2) {
            bI1 -= bI2;
            cnt++;
        }
        return lng2vec(cnt);
    }
public:
    bigInt() {
        v.clear();
    }
    bigInt(long long n) {
        v = lng2vec(n);
        trimPre0(v);
    }
    bigInt(Container c) {
        v = c;
        trimPre0(v);
    }
    bigInt(string s) {
        for (int i = s.size() - 1; i >= 0; i--)v.push_back(s[i] - '0');
        trimPre0(v);
    }
    bigInt & operator = (const bigInt & bI) {
        this->v = bI.v;
        return *this;
    }
    bool operator < (const bigInt & bI2) const {
        if (v.size() != bI2.v.size())return v.size() < bI2.v.size();
        for (int i = v.size() - 1; i >= 0; i--) {
            if (v[i] != bI2.v[i])return v[i] < bI2.v[i];
        }
        return false;
    }
    bool operator > (const bigInt & bI2) const {
        if (v.size() != bI2.v.size())return v.size() > bI2.v.size();
        for (int i = v.size() - 1; i >= 0; i--) {
            if (v[i] != bI2.v[i])return v[i] > bI2.v[i];
        }
        return false;
    }
    bool operator <= (const bigInt & bI2) const {
        return (*this)<bI2 || (*this)==bI2;
    }
    bool operator >= (const bigInt & bI2) const {
        return (*this)>bI2 || (*this)==bI2;
    }
    bool operator == (const bigInt & bI2) const {
        return v == bI2.v;
    }
    bigInt & operator += (const bigInt & bI2) {
        Container & s1 = v;
        const Container & s2 = bI2.v;
        if (s1.size() < s2.size())s1.resize(s2.size());
        int s1Len = s1.size(), s2Len = s2.size();
        for (int i = 0; i < s2Len; i++)s1[i] += s2[i];
        for (int i = 0; i < s1Len - 1; i++)if (s1[i] > 9) {
            s1[i + 1] += s1[i] / 10;
            s1[i] %= 10;
        }
        if (s1[s1Len - 1] > 9) {
            s1.push_back(s1[s1Len - 1] / 10);
            s1[s1Len - 1] %= 10;
        }
        return *this;
    }
    bigInt operator + (const bigInt & bI2) const {
        bigInt bI1 = *this;
        bI1 += bI2;
        return bI1;
    }
    bigInt & operator -= (const bigInt & bI2) {
        Container & s1 = v;
        const Container & s2 = bI2.v;
        bool flag = false;
        if ((*this) < bI2)flag = true, s1.resize(s2.size());
        int s1Len = s1.size(), s2Len = s2.size();
        for (int i = 0; i < s2Len; i++)s1[i] -= s2[i];
        if (flag)for (int i = 0; i < s2Len; i++)s1[i] = -s1[i];
        for (int i = 0; i < s1Len - 1; i++)if (s1[i] < 0) {
            s1[i + 1] -= 1;
            s1[i] += 10;
        }
        trimPre0(s1);
        return *this;
    }
    bigInt operator - (const bigInt & bI2) const {
        bigInt bI1 = *this;
        bI1 -= bI2;
        return bI1;
    }
    bigInt operator * (const bigInt & bI2) const {
        const Container & v1 = v;
        const Container & v2 = bI2.v;
        Container v3;
        v3.resize(v1.size() + v2.size(), 0);
        for (int i = 0; i < (int)v2.size(); i++) {
            for (int j = 0; j < (int)v1.size(); j++) {
                v3[i + j] += v2[i] * v1[j];
            }
        }
        bIsort(v3);
        return bigInt(trimPre0(v3));
    }
    bigInt & operator *= (const bigInt & bI2) {
        *this = (*this)*bI2;
        return *this;
    }
    bigInt operator / (const unsigned long long & bI2) const {
        const Container & v1 = v;
        long long v2 = bI2;
        Container v3;
        long long div = 0;
        for (int i = v1.size() - 1; i >= 0; i--) {
            div *= 10;
            div += v1[i];
            if (div < v2) {
                v3.push_back(0);
                continue;
            }
            Container tmp = lng2vec(div / v2);
            v3.insert(v3.end(), tmp.begin(), tmp.end());
            div %= v2;
        }
        reverse(v3.begin(), v3.end());
        return bigInt(trimPre0(v3));
    }
    unsigned long long operator % (const unsigned long long & bI2) const {
        const Container & v1 = v;
        unsigned long long v2 = bI2;
        unsigned long long div = 0;
        for (int i = v1.size() - 1; i >= 0; i--) {
            div *= 10;
            div += v1[i];
            if (div < v2)continue;
            div %= v2;
        }
        return div % v2;
    }
    bigInt operator / (const bigInt & bI2) const {
        const Container & v1 = v;
        const Container & v2 = bI2.v;
        Container v3;
        bigInt div = 0;
        for (int i = v1.size() - 1; i >= 0; i--) {
            div *= 10;
            div += v1[i];
            if (div < v2) {
                v3.push_back(0);
                continue;
            }
            Container tmp = easyDiv(div, v2);
            v3.insert(v3.end(), tmp.begin(), tmp.end());
        }
        reverse(v3.begin(), v3.end());
        return bigInt(trimPre0(v3));
    }
    bigInt & operator /= (const bigInt & bI2) {
        *this = (*this)/bI2;
        return *this;
    }
    bigInt operator % (const bigInt & bI2) const {
        const Container & v1 = v;
        const Container & v2 = bI2.v;
        bigInt div = 0;
        for (int i = v1.size() - 1; i >= 0; i--) {
            div *= 10;
            div += v1[i];
            if (div < v2)continue;
            easyDiv(div, v2);
        }
        return div;
    }
    bigInt & operator %= (const bigInt & bI2) {
        *this = (*this) % bI2;
        return *this;
    }
    friend istream& operator >> (istream& in, bigInt & bI) {
        string s;
        in >> s;
        bI.v.clear();
        for (int i = s.size() - 1; i >= 0; i--) bI.v.push_back(s[i] - '0');
        trimPre0(bI.v);
        return in;
    }
    friend ostream& operator << (ostream& out, bigInt & bI) {
        for (int i = bI.v.size() - 1; i >= 0; i--) out << (char)(bI.v[i] + '0');
        return out;
    }
    void scan() {
        v.clear();
        scanf(" ");
        char c;
        do {
            c = getchar();
            if (c <= '9'&&c >= '0')v.push_back(c - '0');
            else {
                ungetc(c, stdin);
                break;
            }
        } while (1);
        reverse(v.begin(), v.end());
        trimPre0(v);
    }
    void print() {
        for (int i = v.size() - 1; i >= 0; i--) {
            printf("%d", v[i]);
        }
    }
};

洛谷 P1439 【模板】最长公共子序列

这题不是LCS的裸题啊……。。基本上照抄的题解:
https://pks-loving.blog.luogu.org/junior-dynamic-programming-dong-tai-gui-hua-chu-bu-ge-zhong-zi-xu-lie

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<iostream>
using namespace std;
int a[100005],b[100005],map[100005],f[100005];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){cin>>a[i];map[a[i]]=i;}
    for(int i=1;i<=n;i++){cin>>b[i];f[i]=0x7fffffff;}
    int len=0;
    f[0]=0;
    for(int i=1;i<=n;i++){
        int l=0,r=len,mid;
        if(map[b[i]]>f[len])f[++len]=map[b[i]];
        else{
            while(l<r){
                mid=(l+r)>>1;
                if(f[mid]>map[b[i]])r=mid;
                else l=mid+1;
            }
            f[l]=min(map[b[i]],f[l]);
        }
    }
    cout<<len;
}

洛谷 P2261 [CQOI2007]余数求和

新学的知识点:除法分块。
题解:https://www.luogu.org/blog/Capella/solution-p2261

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<iostream>
#define ll long long
using namespace std;
ll n,k,ans;
int main(){
    cin>>n>>k;
    for(ll l=1,t,r;l<=n;l=r+1){
        t=k/l;
        if(t==0)r=n;
        else r=min(k/t,n);
        ans-=t*(l+r)*(r-l+1)/2;
    }
    cout<<ans+n*k;
}

洛谷 P2327 [SCOI2005]扫雷

还以为是搜索,写了半天之后懒得写了看看题解才发现出问题了。。
题解:https://www.luogu.org/blog/user31898/solution-p2327

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<iostream>
#include<cstring>
using namespace std;
int n;
int arr1[10005],arr2[10005];
bool f(){
    for(int i=2;i<=n+1;i++){
        arr2[i]=arr1[i-1]-arr2[i-1]-arr2[i-2];
        if(arr2[i]!=1&&arr2[i]!=0)return false;
        if(i==n+1&&arr2[i]!=0)return false;
    }
    return true;
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)cin>>arr1[i];
    int num=0;
    arr2[1]=0;
    if(f())num++;
    arr2[1]=1;
    if(f())num++;
    cout<<num;
}

洛谷 P1641 [SCOI2010]生成字符串

感谢乘法逆元!感谢快速幂!感谢费马小定理!(逃
参考题解:
https://www.luogu.org/blog/user29936/solution-p1641
https://www.luogu.org/blog/user35379/solution-p1641

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<iostream>
#define ll long long
#define MOD 20100403
using namespace std;
ll quickpow(ll a,ll b){
    if(b==0)return 1;
    ll re=quickpow(a,b/2)%MOD;
    re=re*re%MOD;
    if(b%2!=0)re=re*a%MOD;
    return re%MOD;
}
ll inv(ll x){
    return quickpow(x,MOD-2)%MOD;
}
ll C(ll n,ll m){
    ll re=1;
    for(ll i=n;i>=n-m+1;i--){
        re=re*i%MOD;
    }
    ll fact=1;
    for(ll i=1;i<=m;i++){
        fact=fact*i%MOD;
    }
    ll invFact=inv(fact);
    return re*invFact%MOD;
}
int main(){
    ll n,m;
    cin>>n>>m;
    cout<<(C(n+m,n)%MOD-C(n+m,n+1)%MOD+MOD)%MOD;
}