D1T1

对于一个格点图,类似于男人八题T1,我们这道题也可以先找出矩形,之后再找出不是矩形的
平行四边形。
0 0 0 0 0
0 0 0 0 0
我们采取上次同样的策略来找,发现规律:
S = (3 + 2 + 1) (2 + 1) 1 (1 + 2) (1 + 2 + 3)
怎么总结呢?
我们发现:其实就是1 * n + ... + n * n - 2 - 6 - 12- ...我们再次发现(我们好厉害)
后面减去的那一坨其实就是2 * (S的一半)
ok
再加上之前的矩形
规律为:(2n + 1)n(n + 1)/6

D1T2

对于这道题的话其实出题人已经很良心了,在输入的时候提示了,很容易想到折半搜索,
因为我们发现对于每个颜色的数量一定为n所以当我们在前半个n找出了p个的某个颜色,那么
这个某个颜色在另外的区间一定有n - p个,那么我们怎么统计合法方案呢?hash!!!
我们现在已经开始统计后半个区间,如果合法那么当前颜色的总hash值一定会有前半个的另外一个颜色的总hash值和它相等
//挂题原因
不会用map,实际上它很简单呢!!
//可爱的小分割线
code:
#include<cstdio>
#include<iostream>
#include<map>
#define ll long long
using namespace std;

const long long mod = 1e18 + 17;

map<ll,int>res[100];
long long ans,d[100];
int n,p,q;
char c[100];



void dfs1(int u,ll col)
{
    if(u == n + 1)
    {
        //cout << col << endl;
        res[p][col]++;
        return;
    }
    ll x;
    p++;
    x = (col + d[p] * (c[u] - 'a' + 1)) % mod;
    dfs1(u + 1,x);
    p--;
    q++;
    x = (col - d[q] * (c[u] - 'a' + 1)) % mod;
    dfs1(u + 1,x);
    q--;
}

void dfs2(int u,ll col)
{
    if(u == n)
    {
        //cout << col << endl;
        ans += res[q][col];
        return;
    }
    ll x;
    p++;
    x = (col - d[p] * (c[u] - 'a' + 1)) % mod;
    dfs2(u - 1,x);
    p--;
    q++;
    x = (col + d[q] * (c[u] - 'a' + 1)) % mod;
    dfs2(u - 1,x);
    q--;
}

int main()
{
    cin >> n;
    scanf("%s",c + 1);
    d[1] = 31;
    for(int i = 2;i <= n;i += 1)
        d[i] = d[i - 1] * 31 % mod;
    dfs1(1,0);
    //cout << endl;
    dfs2(2 * n,0);
    cout << ans << endl;
    return 0;
}

D1T3

聪聪叹气,审题是个好东西,对于这个题我们发现统计内含整点个数,其实就是找到这个三角形
为什么呢?因为我们有公式S = a + b/2 - 1,那么出题人还要求锐角三角形,可我们还有
a ^ 2 + b ^ 2 > c ^ 2(我们有的挺多)这样的话我们就把问题转化成立找三角形问题,
怎么找呢,三元环计数!三元环做法详解直接上链接
https://www.cnblogs.com/Dance-Of-Faith/p/9759794.html
注意重边的代价要翻倍毕竟一个三元环的度位2,1,0
b咋算??getgcd!
OK完美
//挂题原因
审题失误以为相交边不会产生影响,并且我还不会三元环(我好菜娅),甚至还不会map
虽然我现在还是没A,不过还是感觉进步了,dalao看看否哪里WA了>嘤嘤嘤
//我是分割线
#include<cstdio>
#include<iostream>
#include<map>
#include<algorithm>
#include<cmath>
using namespace std;

const int MAXN = 3e5 + 17;
const int mod = 998244353;

struct node
{
    int v,next;
}e[MAXN];

map<int,map<int,int> >q;
map<int,map<int,int> >w;
map<int,map<int,double> >d;
map<int,map<int,int> > h;
int tot,top,head[MAXN],vis[MAXN],a1[MAXN],a2[MAXN],b1[MAXN],b2[MAXN],in[MAXN];

int getgcd(int a,int b)
{
    if(a < b)swap(a,b);
    if(b == 0)return a;
    return getgcd(b,a % b);
}

long long gets(double x,double y,double z)
{
    double p = (x + y + z) / 2;
    return sqrt(p * (p - x) * (p - y) * (p - z));
}

void add(int u,int v)
{
    e[++tot].v = v;
    e[tot].next = head[u];
    head[u] = tot;
}

bool rui(int x,int y,int z)
{
    if(x * x + y * y <= z * z)return 0;
    if(x * x + z * z <= y * y)return 0;
    if(y * y + z * z <= x * x)return 0;
    return 1;
}

double getd(double x,double y)
{
    return sqrt(x * x + y * y);
}

int main()
{
    int n;
    cin >> n;
    for(int i = 1;i <= n;i += 1)
    {
        cin >> a1[i] >> b1[i] >> a2[i] >> b2[i];
        if(!q[a1[i]][b1[i]])q[a1[i]][b1[i]] = ++top;
        if(!q[a2[i]][b2[i]])q[a2[i]][b2[i]] = ++top;
        w[q[a1[i]][b1[i]]][q[a2[i]][b2[i]]] = w[q[a2[i]][b2[i]]][q[a1[i]][b1[i]]] = getgcd(abs(a2[i] - a1[i]),abs(b2[i] - b1[i]));
        d[q[a1[i]][b1[i]]][q[a2[i]][b2[i]]] = d[q[a2[i]][b2[i]]][q[a1[i]][b1[i]]] = getd(abs(a2[i] - a1[i]),abs(b2[i] - b1[i]));
        in[q[a1[i]][b1[i]]]++;
        in[q[a2[i]][b2[i]]]++;
    }
    for(int i = 1;i <= n;i += 1)
    {
        if(h[q[a1[i]][b1[i]]][q[a2[i]][b2[i]]])
        {
            h[q[a1[i]][b1[i]]][q[a2[i]][b2[i]]]++;
            h[q[a2[i]][b2[i]]][q[a1[i]][b1[i]]] = h[q[a1[i]][b1[i]]][q[a2[i]][b2[i]]] ;
            //w[q[a1[i]][b1[i]]][q[a2[i]][b2[i]]] = w[q[a2[i]][b2[i]]][q[a1[i]][b1[i]]] = w[q[a1[i]][b1[i]]][q[a2[i]][b2[i]]] + h[q[a1[i]][b1[i]]][q[a2[i]][b2[i]]];
            continue;
        }
        if(in[q[a1[i]][b1[i]]] < in[q[a2[i]][b2[i]]])
            add(q[a2[i]][b2[i]],q[a1[i]][b1[i]]);
        if(in[q[a1[i]][b1[i]]] > in[q[a2[i]][b2[i]]])add(q[a1[i]][b1[i]],q[a2[i]][b2[i]]);
        if(in[q[a1[i]][b1[i]]] == in[q[a2[i]][b2[i]]] && q[a1[i]][b1[i]] < q[a2[i]][b2[i]])
            add(q[a1[i]][b1[i]],q[a2[i]][b2[i]]);
        if(in[q[a1[i]][b1[i]]] == in[q[a2[i]][b2[i]]] && q[a2[i]][b2[i]] < q[a1[i]][b1[i]])
            add(q[a2[i]][b2[i]],q[a1[i]][b1[i]]);
        h[q[a1[i]][b1[i]]][q[a2[i]][b2[i]]] = h[q[a2[i]][b2[i]]][q[a1[i]][b1[i]]] = 1;
    }
    long long ans = 0;
    for(int k = 1;k <= n;k += 1)
    {
        for(int i = head[k];i;i = e[i].next)
        {
            int v = e[i].v;
            vis[v] = k;
        }
        for(int i = head[k];i;i = e[i].next)
        {
            int v = e[i].v;
            for(int r = head[v];r;r = e[r].next)
            {
                int u = e[r].v;
                //cout << k << v << u << endl;
                if(vis[u] == k)
                {
                    if(!rui(d[k][v],d[v][u],d[k][u]))continue;
                    long long s = gets(d[k][v],d[v][u],d[k][u]);
                    ans += (s - (w[k][v] + w[v][u] + w[k][u]) / 2 + 1) * h[k][u] * h[k][v] * h[v][u];
                    ans %= mod;
                }
            }
        }
    }
    cout << ans << endl;
    return 0;
}

D2T1

问题转化,求出一种方案使得这个新图存在一个环并且所有点联通,我们再把问题细化,
所有点联通是个啥!最小生成树!咋样存在环?连一条不在树中最小边!!!
//挂题原因
小字没看见呜呜呜呜(论我到底有多粗心)
//没有存在感的分割线
code:
代码搁机房了嘤嘤嘤

D2T2

满分算法还没搞懂(待更新)

D2T3

现场,聪聪贪心拿了40,但是正解的贪心还没调出来(待更新,可能是我菜了吧)