计蒜客NOIP2017提高组模拟赛(三)day2-数三角形

传送门

这题有点坑啊

设A为两边颜色不同的角,B为两边颜色相同的角

那么考虑三种三角形:异色,同色,其他

对于任何一个异色三角形,一定会有三个颜色不同的角,

对于任何一个同色三角形,一定会有零个颜色不同的角,

对于任何一个其他三角形,一个会有两个颜色不同的角,

那么A一定等于异色三角形数目*3+其他三角形数目*2

对于任何一个异色三角形,一定会有零个颜色相同的角,

对于任何一个同色三角形,一定会有三个颜色相同的角,

对于任何一个其他三角形,一个会有一个颜色相同的角,

那么B一定等于同色三角形数目*3+其他三角形数目*1

设异色为x种,同色为y中,其他为z种

则A=3x+2z B=3y+z

题目要求的就是3x-6y

发现就是A-2B

然后就水过了~

PS这数据范围10^5也不对啊。。。难道是考虑高精度么。。。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<map>
 7 #include<set>
 8 #include<queue>
 9 #include<vector>
10 #define INF 0x7f7f7f7f
11 #define pii pair<int,int>
12 #define ll long long
13 using namespace std;
14 int n,m;
15 namespace solve2
16 {
17     int G[505][505];
18     int n,m;
19     void solve(){
20         n=::n,m=::m;
21         for(int i=1;i<=m;i++){
22             int x,y,c;
23             scanf("%d%d%d",&x,&y,&c);
24             G[x][y]=G[y][x]=c;
25         }
26         ll ans=0;
27         for(int i=1;i<=n;i++){
28             for(int j=i+1;j<=n;j++){
29                 for(int k=j+1;k<=n;k++){
30                     if(G[i][j]==G[j][k]&&G[j][k]==G[i][k]){
31                         ans-=6;
32                     }
33                     else if(G[i][j]!=G[j][k]&&G[j][k]!=G[i][k]&&G[i][j]!=G[i][k]){
34                         ans+=3;
35                     }
36                 }
37             }
38         }
39         printf("%lld\n",ans);
40     }
41 }
42 namespace solve1
43 {
44     ll A,B;
45     int a[100005][2];
46     int n,m;
47     void solve(){
48         n=::n,m=::m;
49         for(int i=1;i<=m;i++){
50             int x,y,c;
51             scanf("%d%d%d",&x,&y,&c);c--;
52             a[x][c]++,a[y][c]++;
53         }
54         for(int i=1;i<=n;i++){
55             ll s1=n-1-a[i][0]-a[i][1];
56             ll s2=a[i][0];
57             ll s3=a[i][1];
58             A+=s1*s2+s1*s3+s2*s3;
59             B+=s1*(s1-1)/2+s2*(s2-1)/2+s3*(s3-1)/2;
60         }
61         printf("%lld",A-2*B);
62     }
63 }
64 int read(){
65     int x=0,f=1;char ch=getchar();
66     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
67     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
68     return x*f;
69 }
70 int main()
71 {
72 //    freopen("data.in","r",stdin);
73     n=read(),m=read();
74     if(n<=500){
75         solve2::solve();
76     }
77     else{
78         solve1::solve();
79     }
80     return 0;
81 }

 

posted @ 2017-10-27 22:44  white_hat_hacker  阅读(387)  评论(0编辑  收藏  举报