2021-8-2Codeforces Round #736

A

#include <bits/stdc++.h>
using namespace std;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	int t;
	cin >> t;
	while(t--) {
		int p;
		cin >> p;
		cout << "2 " << p-1 << "\n";
	}
	return 0;
}
Written by Agnimandur (Runtime: 109ms)

import java.io.*;
import java.util.*;
 
public class solution {
    public static void main(String[] args) {
        FastScanner sc = new FastScanner();
        PrintWriter pw = new PrintWriter(System.out);
        
        int T = sc.ni();
        for (int t = 0; t < T; t++) {
        	int P = sc.ni();
        	int a = 2;
        	int b = P-1;
        	pw.println(a + " " + b);
        }
        
        pw.close();
    }
    
    static class FastScanner {
        BufferedReader br;
        StringTokenizer st;
 
        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }
 
        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
 
        int ni() {
            return Integer.parseInt(next());
        }
 
        long nl() {
            return Long.parseLong(next());
        }
 
        double nd() {
            return Double.parseDouble(next());
        }
 
        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}

B

Written by arvindr9 (Runtime: 31ms)

#include <bits/stdc++.h>
using namespace std;
 
int t;
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        string st, tt;
        cin >> st >> tt;
        int ans = 0;
        vector<bool> taken(n);
        for (int j = 0; j < n; j++) {
            if (tt[j] == '1') {
                for (int i = j - 1; i <= j + 1; i++) {
                    if (i >= 0 and i < n) {
                        if (!taken[i]) {
                            if ((st[i] == '1' and i != j) or (st[i] == '0' and i == j)) {
                                taken[i] = 1;
                                ans++;
                                break;
                            }
                        }
                    }
                }
            }
        }
        cout << ans << "\n";
    }
} 
Written by Agnimandur (Runtime: 124ms)

import java.io.*;
import java.util.*;
import java.math.*;

public class solution {
    static FastScanner sc;
    static PrintWriter pw;

    public static void main(String[] args) {
        sc = new FastScanner();
        pw = new PrintWriter(System.out);
        
        int Q = sc.ni();
        for (int q = 0; q < Q; q++) {
            int N = sc.ni();
            String enemy = sc.next();
            boolean[] free = new boolean[N]; //enemy pawns available for capture
            for (int i = 0; i < N; i++) {
                if (enemy.charAt(i)=='1')
                    free[i] = true;
            }
            String gregor = sc.next();
        	
            int ans = 0;
            for (int i = 0; i < N; i++) {
                if (gregor.charAt(i)=='0')
                    continue;
        		
        	if (i>0 && free[i-1]) {
        	    free[i-1] = false;
        	    ans++;
        	} else if (enemy.charAt(i)=='0') {
                    //no enemy pawn in our path
        	    ans++;
        	} else if (i < N-1 && free[i+1]) {
        	    free[i+1] = false;
        	    ans++;
        	}
            }
            pw.println(ans);
        }

        pw.close();
    }

    static class FastScanner {
        BufferedReader br;
        StringTokenizer st;
 
        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in), 32768);
            st = null;
        }
 
        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
 
        int ni() {
            return Integer.parseInt(next());
        }

        int[] intArray(int N) {
            int[] ret = new int[N];
            for (int i = 0; i < N; i++)
                ret[i] = ni();
            return ret;
        }
 
        long nl() {
            return Long.parseLong(next());
        }

        long[] longArray(int N) {
            long[] ret = new long[N];
            for (int i = 0; i < N; i++)
                ret[i] = nl();
            return ret;
        }

        double nd() {
            return Double.parseDouble(next());
        }
 
        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}

C
Due to the queries, actually simulating the process each time will be too expensive.

Proof that the Process will End: Assume after round x, xi nobles are killed. If xi=0, then the state of the graph doesn’t change, so the process will have ended. If xi>0, then the number of nobles decreases. Thus, the maximum number of rounds the process can last is N, so it must end.

Lemma 1: At the end of the process, no two nobles will still be friends.

Proof by Contradiction: Assume that nobles u and v (assume WLOG that u<v) are still friends and the process is over. In order for u to avoid being killed, there must be a noble w weaker than u that is also a friend of u. The same logic then applies to w, and we have an infinite descent argument. There are only a finite number of nobles weaker than u, so there will be a contradiction.

Lemma 2: If all of a noble’s friends are weaker than it, that noble cannot be killed.

Direct Proof: Since none of the noble’s friends are stronger than it, it is impossible for all of them to be stronger at any point in the process.

Final Idea: By combining Lemmas 1 and 2, we can prove that if ALL of a noble’s friends are weaker than it, that noble survives, otherwise it will die. This leads to the solution.

Maintain in an array the number of nobles weaker than noble i. Since the updates guarantee that the edge being removed/added does/doesn’t exist respectively, we only need to keep track of the number of edges of each noble. Essentially, a noble survives if and only if . After linear precomputation, updates and queries take constant time.weaker[i]==edges[i]

The time complexity is O(N+M+Q).

Written by m371 (Runtime: 202ms)

#include <bits/stdc++.h>
using namespace std;
const int N=200050;
int cnt[N],ans;
int main(){
    int n,m;scanf("%i %i",&n,&m);
    for(int i=1;i<=m;i++){
        int u,v;scanf("%i %i",&u,&v);
        if(u>v)swap(u,v);
        cnt[u]++;
        if(cnt[u]==1)ans++;
    }
    int q;scanf("%i",&q);
    while(q--){
        int t;scanf("%i",&t);
        if(t==1){
            int u,v;scanf("%i %i",&u,&v);
            if(u>v)swap(u,v);
            cnt[u]++;
            if(cnt[u]==1)ans++;
        }else if(t==2){
            int u,v;scanf("%i %i",&u,&v);
            if(u>v)swap(u,v);
            cnt[u]--;
            if(cnt[u]==0)ans--;
        }else printf("%i\n",n-ans);
    }
    return 0;
}
Written by Agnimandur (Runtime: 249ms)

import java.io.*;
import java.util.*;
 
public class solution {
    static FastScanner sc;
    static PrintWriter pw;

    static int[] weaker;
    static int[] edges;
    static int ans;
 
    public static void main(String[] args) {
        sc = new FastScanner();
        pw = new PrintWriter(System.out);

        int N = sc.ni();
        int M = sc.ni();
        weaker = new int[N];
        edges = new int[N];
        for (int i = 0; i < M; i++) {
            int a = sc.ni()-1;
            int b = sc.ni()-1;
            change(a,b,1);
        }
        ans = 0;
        for (int i = 0; i < N; i++) {
            ans += survive(i);
        }

        int Q = sc.ni();
        for (int q = 0; q < Q; q++) {
            int type = sc.ni();
            if (type == 1 || type == 2) {
                int a = sc.ni()-1;
                int b = sc.ni()-1;
                update(a,b,type);
            } else {
                pw.println(ans);
            }
        }
        pw.close();
    }

    //process an update
    public static void update(int a, int b, int type) {
        int prev = survive(a)+survive(b);
        if (type==1) {
            change(a,b,1);
        } else {
            change(a,b,-1);
        }
        int next = survive(a)+survive(b);

        ans += (next-prev);
    }

    public static void change(int a, int b, int x) {
        edges[a] += x;
        edges[b] += x;
        if (a > b)
            weaker[a] += x;
        else
            weaker[b] += x;
    }

    //does noble a survive?
    public static int survive(int a) {
        if (weaker[a]==edges[a])
            return 1;
        else
            return 0;
    }

    static class FastScanner {
        BufferedReader br;
        StringTokenizer st;
 
        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in), 32768);
            st = null;
        }
 
        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
 
        int ni() {
            return Integer.parseInt(next());
        }
    }
}

D

Written by emorgan5289 (Runtime: 218ms)

#include <bits/stdc++.h>
using namespace std;
 
using ll = long long;
const int inf = 1e9+10;
const ll inf_ll = 1e18+10;
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define cmax(x, y) (x = max(x, y))
#define cmin(x, y) (x = min(x, y))
 
template<typename it, typename bin_op>
struct sparse_table {
 
    using T = typename remove_reference<decltype(*declval<it>())>::type;
    vector<vector<T>> t; bin_op f;
 
    sparse_table(it first, it last, bin_op op) : t(1), f(op) {
        int n = distance(first, last);
        t.assign(32-__builtin_clz(n), vector<T>(n));
        t[0].assign(first, last);
        for (int i = 1; i < t.size(); i++)
            for (int j = 0; j < n-(1<<i)+1; j++)
                t[i][j] = f(t[i-1][j], t[i-1][j+(1<<(i-1))]);
    }
 
    // returns f(a[l..r]) in O(1) time
    T query(int l, int r) {
        int h = floor(log2(r-l+1));
        return f(t[h][l], t[h][r-(1<<h)+1]);
    }
};
 
int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
    int t; cin >> t;
    while (t--) {
        ll n; cin >> n;
        vector<ll> a(n), d(n-1);
        for (int i = 0; i < n; i++)
            cin >> a[i];
        for (int i = 0; i < n-1; i++)
            d[i] = abs(a[i+1]-a[i]);
        sparse_table g(all(d), [](ll x, ll y){
            return __gcd(x, y);
        });
        int j = 0, ans = 1;
        for (int i = 0; i < n-1; i++) {
            while (j <= i && g.query(j, i) == 1) j++;
            cmax(ans, i-j+2);
        }
        cout << ans << "\n";
    }
}
Written by Agnimandur (Runtime: 499ms)

import java.io.*;
import java.util.*;
 
public class Main {
    static final int INF = 50000000;
    public static void main(String[] args) {
        FastScanner sc = new FastScanner();
        PrintWriter pw = new PrintWriter(System.out);
        
        int Q = sc.ni();
        int P = 18;
        for (int q = 0; q < Q; q++) {
            int N = sc.ni();
            long[] a = new long[N];
            for (int i = 0; i < N; i++)
                a[i] = sc.nl();
            
            long[][] table = new long[P][N-1];
            for (int i = 0; i < N-1; i++)
                table[0][i] = Math.abs(a[i+1]-a[i]);
            for (int i = 1; i < P; i++) {
                for (int j = 0; j < N-(1<<i); j++) {
                    table[i][j] = gcd(table[i-1][j],table[i-1][j+(1<<(i-1))]);
                }
            }
            int ans = 1;
            for (int j = 0; j < N-1; j++) {
                if (table[0][j]==1) continue;
                int cur = j;
                long g = INF;
                for (int i = P-1; i >= 0; i--) {
                    if (cur==N-1) break;
                    if (table[i][cur] >= 2 && (g==INF||gcd(g,table[i][cur])>=2)) {
                        if (g==INF)
                            g = table[i][cur];
                        else
                            g = gcd(g,table[i][cur]);
                        cur += (1<<i);
                    }
                }
                ans = Math.max(ans,cur-j+1);
            }
            pw.println(ans);
        }
        pw.close();
    }
    
    //Find the GCD of two numbers
    public static long gcd(long a, long b) {
        if (a < b)
            return gcd(b,a);
        if (b == 0)
            return a;
        else
            return gcd(b,a%b);
    }

    static class FastScanner {
        BufferedReader br;
        StringTokenizer st;
 
        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }
 
        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
 
        int ni() {
            return Integer.parseInt(next());
        }
 
        long nl() {
            return Long.parseLong(next());
        }
 
        double nd() {
            return Double.parseDouble(next());
        }
 
        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}

E
For a given x, we want to compute ∑Ni=1(3ix), which can be solved with a combinatorial dynamic programming.

Define the array dp[x][m] (dimensions: N+1×3), which computes the sum ∑N−1i=0(3i+mx). Under this definition, ans[x]=dp[x][0]+(3Nx), where ans is what we want to find.

Under the definition of the dp, we can make the following mathematical observations.

dp[x][0]+dp[x][1]+dp[x][2]=∑3N−1i=0(ix), since term i belongs to the array with m=imod3. This summation can be condensed with the Hockey Stick Identity into (3Nx+1).

By repeated uses of Pascal’s Identity, we get equations (2) and (3), giving us a system of 3 equations with 3 new unknowns, which can easily be solved.

∑2m=0dp[x][m]=(3Nx+1).
dp[x][1]=dp[x][0]+dp[x−1][0]
dp[x][2]=dp[x][1]+dp[x−1][1]
The base case is that dp[0][0]=dp[0][1]=dp[0][2]=N. Each query can now be answered trivially.

The time complexity is O(N+Q) with combinatorial precomputation.

Written by Agnimandur (Runtime: 218ms)

#include <bits/stdc++.h>
 
#define ll long long
#define sz(x) ((int) (x).size())
#define all(x) (x).begin(), (x).end()
#define vi vector<int>
#define vl vector<long long>
#define REP(i,a) for (int i = 0; i < (a); i++)
#define add push_back
using namespace std;
 
const ll MOD = 1000000007LL;
 
 
 
int ni() {
    int x; cin >> x;
    return x;
}
 
struct Combo {
    vl facs;
    vl invfacs;
    int N;
 
    Combo(int N) {
        this->N=N;
        facs.assign(N+1,0);
        invfacs.assign(N+1,0);
        facs[0] = 1;
        for (int i = 1; i <= N; i++) {
            facs[i] = (facs[i-1]*i)%MOD;
        }
        invfacs[N] = power(facs[N],MOD-2);
        for (int i = N-1; i >= 0; i--) {
            invfacs[i] = (invfacs[i+1]*(i+1))%MOD;
        }
    }
 
    ll choose(int n, int k) {
        if (n<0||k<0||n<k) return 0LL;
        ll denInv = (invfacs[k]*invfacs[n-k])%MOD;
        ll ans = (facs[n]*denInv)%MOD;
        return ans;
    }
 
    ll power(ll x, ll y) {
        ll ans = 1;
        x %= MOD;
        while (y > 0) {
            if (y%2==1) ans = (ans*x)%MOD;
            y /= 2;
            x = (x*x)%MOD;
        }
        return ans;
    }
};
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
 
    int N = ni();
    Combo c(3*N);
    ll DIV3 = c.power(3,MOD-2);
 
    const int M = 1000000;
    ll dp[3*M+1][3];
    REP(i,3) dp[0][i] = N;
 
    for (int x = 1; x < 3*N; x++) {
        //solve the system of equations
        dp[x][0] = ((c.choose(3*N,x+1)-2*dp[x-1][0]-dp[x-1][1]+3*MOD)*DIV3)%MOD;
        dp[x][1] = (dp[x][0]+dp[x-1][0])%MOD;
        dp[x][2] = (dp[x][1]+dp[x-1][1])%MOD;
    }
    
    int Q = ni();
    REP(q,Q) {
        int x = ni();
        if (x==3*N)
            cout << "1\n";
        else
            cout << (dp[x][0]+c.choose(3*N,x))%MOD << '\n';
    }
}

F1
Every set of 3 fenceposts forms a lattice triangle We want to find the number of such lattice triangles that have an odd number of interior points. Since all the coordinates are even, the area is automatically even as well. By Pick’s Theorem, area=I+B2−1, so 2⋅area=2I+B−2. I is the number of interior points, and B is the number of boundary points, for an arbitrary triangle formed by 3 fenceposts.

Let A=2⋅area, so A=2I+B−2. Since I is odd, taking both sides modulo 4 we get that A≡Bmod4. Since the area is an even integer, A is a multiple of 4, so we get that A≡B≡0mod4.

Let’s define the boundary count of a segment to be the number of lattice points on it, minus 1. It can be proven that the boundary count of the segment connecting (x1,y1) and (x2,y2) is gcd(|x2−x1|,|y2−y1|).

In this problem, we only care about what the boundary count is modulo 4. Since all the coordinates are even, the GCD is guaranteed to be even, so the boundary count is either 0 or 2 mod 4. For the segment connecting (x1,y1) and (x2,y2) call its boundary count b.

b≡0mod4 IFF x1≡x2mod4 AND y1≡y2mod4.
b≡2mod4 in all other situations.
Key Idea: Turn fence post (x,y) into (xmod4,ymod4).

Writing the area of a triangle via the shoelace formula, it becomes obvious that the area mod 4 won’t change when the coordinates are modded by 4. Additionally, by our work above, B (the sum of the boundary counts for the 3 sides of the triangle) is entirely dependent on the coordinates mod 4.

Let cnt[x][y] be an array counting the number of points that fall into each category based on the key idea above. Since all coordinates are even, only 4 elements in the cnt array will be nonzero. We can fix each point of the triangle into one of the categories, quickly calculuate A and B, and solve the problem. Be careful not to overcount triangles.

The time complexity is O(N), with a small constant for the counting.

Written by Agnimandur (Runtime: 31ms)

#include <bits/stdc++.h>
#define ll long long
#define REP(i,a) for (int i = 0; i < (a); i++)
using namespace std;

int ni() {
    int x; cin >> x;
    return x;
}
 
ll choose(ll n, ll k) {
    if (n<k) return 0LL;
    
    if (k==2)
        return n*(n-1)/2;
    else
        return n*(n-1)*(n-2)/6;
}
 
// number of boundary points between two points, mod 4
int boundary(int x1, int y1, int x2, int y2) {
    if (x1==x2&&y1==y2)
        return 0;
    else
        return 2;
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
 
    int N = ni();
 
    ll cnt[2][2] = {{0,0},{0,0}};

    REP(i,N) {
        int x = ni();
        int y = ni();
        cnt[(x%4)/2][(y%4)/2] += 1;
    }
 
    ll ans = 0;
    for (int s1 = 0; s1 < 4; s1++) {
        for (int s2 = s1; s2 < 4; s2++) {
            for (int s3 = s2; s3 < 4; s3++) {
                int x1 = s1/2;
                int y1 = s1%2;
                int x2 = s2/2;
                int y2 = s2%2;
                int x3 = s3/2;
                int y3 = s3%2;
                int b1 = boundary(x1,y1,x2,y2);
                int b2 = boundary(x1,y1,x3,y3);
                int b3 = boundary(x2,y2,x3,y3);
                int B = (b1+b2+b3)%4;
 
                if (B==0) {
                    if (s1==s2&&s2==s3) {
                        ans += choose(cnt[x1][y1],3);
                    } else if (s1==s2) {
                        ans += choose(cnt[x1][y1],2)*cnt[x3][y3];
                    } else if (s2==s3) {
                        ans += choose(cnt[x2][y2],2)*cnt[x1][y1];
                    } else {
                        ans += cnt[x1][y1]*cnt[x2][y2]*cnt[x3][y3];
                    }
                }
            }
        }
    }
    cout << ans << '\n';
}

F2
First read (and understand!) the editorial for the easy version of the problem.

Definition: The modularity of a point (x,y) is (x%4,y%4).
Definition: The boundary count of a segment is the number of lattice points on that segment, minus 1.
Lets precompute the array cnt[i][x][y][b] (dimensions N×4×4×4), which equals the number of other points respective to points[i] with modularity (x,y) and with a boundary count mod 4 equal to b. This precomputation can be done in O(N2log107) time, by iterating over every pair of points. The boundary count of the segment (x1,y1) to (x2,y2) is gcd(|x2−x1|,|y2−y1|).

Consider the number of boundary points on the three sides of a triangle, and call them b1,b2,b3. Clearly, B=b1+b2+b3. The key idea is that since B is even, wlog we can assume that b3 is even, and that b1≡b2mod2. The other key idea is that it is easy to figure out if the boundary count is congruent to 0 or 2 mod 4 based on the modularities of the coordinates alone, but it’s impossible if the boundary count is odd.

Let’s fix a point, and count the number of triangles that involve this point. Let’s also iterate over all the relevant modularities of the other two points in the triangle, which range from (0,0) up to (3,3). Let’s also make sure that there are an even number of boundary points on the side opposite the fixed point, which we know almost nothing about. It can be shown that b3≡0mod4 IFF (x1,y1)=(x2,y2), and that b3≡2mod4 IFF x1,x2 have the same parity, and y1,y2 have the same parity, and the previous case doesn’t apply. Finally, make sure that the parity of the boundary count of the two sides next to the fixed point are the same.

Using the precomputed array cnt and the formula for b3, we can quickly find B in this case. Using the Shoelace Formula, we can quickly find what A is modulo 4. If A is even and equal to B, then we know that I must be odd (in the easy version of the problem, we found that A≡Bmod4 IFF I is odd), so all triangles in this class are interesting. Thus, we add to the answer a number roughly equal to cnt[i][x1][y1][b1]⋅cnt[i][x2][y2][b2] (it could be lower due to the potential overcount, if two points fall into the same bucket of the array).

Lastly, be sure not to overcount triangles! In my code, I count each of the EEE triangles (b1,b2,b3 all even) 3 times, and the OOE triangles once.

The time complexity is O(N2log107) (the main part of the solution is approximately O(512N)).

Implementation Note: The bottleneck of the algorithm is computing the GCDs. The simplest optimization that is sufficient for AC is to only calculate N22 GCDs instead of all N2 (since the GCD is commutative). Java requires additional optimizations, such as precomputing small GCDs.

Written by Agnimandur (Runtime: 2886ms)

#include <bits/stdc++.h>
 
#define ll long long
#define sz(x) ((int) (x).size())
#define all(x) (x).begin(), (x).end()
#define vi vector<int>
#define vl vector<long long>
#define pii pair<int, int>
#define pll pair<ll,ll>
#define REP(i,a) for (int i = 0; i < (a); i++)
#define add push_back
using namespace std;
 
int ni() {
    int x; cin >> x;
    return x;
}
 
ll nl() {
    ll x; cin >> x;
    return x;
}
 
double nd() {
    double x; cin >> x;
    return x;
}
 
string next() {
    string x; cin >> x;
    return x;
}
 
 
ll area(ll x1, ll y1, ll x2, ll y2, ll x3, ll y3) {
    return abs(x1*y2+x2*y3+x3*y1-x2*y1-x3*y2-x1*y3)&3;
}
 
ll boundary(ll x1, ll y1, ll x2, ll y2) {
    return __gcd(abs(x1-x2),abs(y1-y2))&3;
}
 
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
 
    int N = ni();
 
    vector<pll> nums;
    vector<pii> mods;
    REP(i,N) {
        ll x = nl();
        ll y = nl();
        nums.add({x,y});
        mods.add({(int)(x&3),(int)(y&3)});
    }
 
    const int MAX_N = 6000;
 
    int cnt[MAX_N][4][4][4] = {0};
    for (int i = 0; i < N; i++) {
        for (int j = i+1; j < N; j++) {
            int b = (int)boundary(nums[i].first,nums[i].second,nums[j].first,nums[j].second);
            cnt[i][mods[j].first][mods[j].second][b] += 1;
            cnt[j][mods[i].first][mods[i].second][b] += 1;
        }
    }
 
    ll eee = 0;
    ll ooe = 0;
    for (int i = 0; i < N; i++) {
        for (int b1 = 0; b1 < 4; b1++) {
            for (int b2 = b1; b2 < 4; b2 += 2) {
                for (int s1 = 0; s1 < 16; s1++) {
                    int firsts2 = (b1<b2) ? 0 : s1;
                    for (int s2 = firsts2; s2 < 16; s2++) {
                        int x1 = s1/4;
                        int y1 = s1%4;
                        int x2 = s2/4;
                        int y2 = s2%4;
                        if (x1%2 != x2%2 || y1%2 != y2%2) continue;
 
                        int b3;
                        int triangles;
                        if (x1==x2 && y1==y2) {
                            b3 = 0;
                            if (b1==b2)
                                triangles = cnt[i][x1][y1][b1]*(cnt[i][x1][y1][b2]-1)/2;
                            else
                                triangles = cnt[i][x1][y1][b1]*cnt[i][x1][y1][b2];
                        } else {
                            b3 = 2;
                            triangles = cnt[i][x1][y1][b1]*cnt[i][x2][y2][b2];
                        }
                        int B = (b1+b2+b3)%4;
                        if (area(nums[i].first,nums[i].second,x1,y1,x2,y2) == B) {
                            if (b1%2==0&&b2%2==0)
                                eee += triangles;
                            else
                                ooe += triangles;
                        }
                    }
                }
            }
        }
    }
    ll ans = eee/3+ooe;
    cout << ans << '\n';
}

总结
毕竟是第一次打,还是蛮爽的
A,B偏思维,不需要什么数据结构或者算法,只要够聪明就行了
C题发现它的测试组数有20万,点数和边数也有20万,所以这个时候去模拟它的增边删边操作代价就变得很昂贵,这个时候就要凭直觉去猜结论,然后(千万不要去想着证明他,因为太浪费时间了)只要自己弄几组测试数据看看这样的结论是不是对的就行了,结论提代码一般都很短

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值