作业题

作业题啦啦啦

前两题题解交上去了忘保存了啦啦啦。。真是个傻逼。。

tsinsen A1278 串珠子

#include <iostream>
#include <cstdio>
#define mod 1000000007
using namespace std;
int n, a[20][20];
long long t[100000], f[100000];
int find(int x){
    if(f[x] != -1)return t[x] - f[x];
    int y = x;long long ff = 0;  
    for(; x; x = (x - 1) & y)
        if(x != y && ((x&(1<<(n - 1))) != 0))
            ff = ((t[y^x] * (t[x] - find(x))) % mod + ff) % mod;   
    if(!ff)f[y] = 1;else f[y] = t[y] - ff;  if(f[y] < 0)f[y] += mod;
    return t[y] - f[y];
}
int main()
{
    scanf("%d", &n);
    memset(f, -1, sizeof(f));
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= n; j ++)scanf("%d", &a[i][j]);  
    for(int k = 1; k < (1<<n); k ++){   t[k]  = 1;
        for(int i = 1; i <= n; i ++)
            for(int j = i + 1; j <= n; j ++)
                if(((k & (1<<(i - 1)))!= 0) && ((k & (1<<(j - 1))) != 0)){t[k] *= (long long)(a[i][j] + 1); t[k] %= mod;}
    }
    cout<<t[(1<<n) - 1] - find((1<<(n))-1)<<endl;
    return 0;
}

hdu4997 biconnected

升级版串珠子。。调了好几个小时 T T 还是在大神帮助下调出来的代码写的丑。。

#include <iostream>
#include <cstdio>
#define mod 1000000007
using namespace std;
int n, m, a[11][11], edge[1200][1200];
long long t[1200], f[1200], h[1200][1200], g[1200];
int find(int x){
    if(f[x] != -1)return t[x] - f[x];
    int k = x ^ (x & (x - 1));
    int y = x;long long ff = 0;  
    for(; x; x = (x - 1) & y)
        if(x != y && (x&k)){int tmp = t[x] - find(x); if(tmp < 0)tmp += mod;
            ff = ((t[y^x] * tmp) % mod + ff) % mod;}   
    if(!ff)f[y] = 1;else f[y] = t[y] - ff;  if(f[y] < 0)f[y] += mod;
    return t[y] - f[y];
}
int geth(int a, int b){ //返回 将a分成若干连通块 连接到b 上的数量
    if(h[a][b] != -1)return h[a][b];
    if(a == 0){h[a][b] = 1; return 1;}
    int y = a, k = a ^ (a & (a - 1)); long long ff = 0;
    if(k == a){h[a][b] = edge[a][b]; return h[a][b];}
    for(; a; a = (a - 1) & y)
        if((a&k)){//cout<<a<<endl;
            long long tmp = t[a] - find(a); if(tmp < 0)tmp += mod;
            ff = ((((geth(y - a, b) * tmp) % mod) * edge[a][b]) % mod + ff) % mod;//printf("%d %d %d %d %d %d %d\n", a, b, y, geth(y - a, b), tmp, edge[a][b], ff);
            }
    h[y][b] = ff;  
    return h[y][b];
}
int finddi(int x){// 返回单连通的数量 
    if(g[x] != -1)return g[x];
    int y = x, k = x ^ (x & (x - 1)); long long ff = 0; 
    if(x == k){g[x] = 0; return 0;}  y = x;
    for(; x; x = (x - 1) & y)
        if(x != y && (x&k)){long long tt = t[x] - find(x); if(tt < 0)tt += mod;//tt 为联通的总数量
            long long tmp = tt - finddi(x); if(tmp < 0)tmp += mod; // tmp为 x 的双联通的数量
            ff = ((geth(y - x, x) * tmp) % mod + ff) % mod; } 
    g[x] = ff;//printf("^^^%d %d\n", y, ff);
    return g[x];
}
int main()
{
    int tt; scanf("%d", &tt); while(tt --){
    scanf("%d%d", &n, &m);
    memset(f, -1, sizeof(f));
    memset(g, -1, sizeof(g));
    memset(h, -1, sizeof(h));
    memset(a, 0, sizeof(a));
    memset(edge, 0, sizeof(edge));
    for(int k = 1; k <= m; k ++){
        int aa, bb; scanf("%d%d", &aa, &bb);
        a[aa][bb] = a[bb][aa] = 1;   
    }
    //init edge    
    for(int p = 0; p < (1<<n); p ++)
        for(int i = 0; i < n; i ++)if(p & (1<<i))
            for(int q = p + 1; q < (1<<n); q ++)
                for(int j = 0; j < n; j ++)if( (q & (1<< j)) && i != j){
                    edge[p][q] += (1 - a[i + 1][j + 1]); edge[q][p] += (1 - a[i + 1][j + 1]);}
  //  for(int ii = 1; ii <= 18; ii ++){
  //      for(int jj = 1; jj <= 18; jj ++)
   //         printf("%d ", edge[ii][jj]);cout<<endl;}
    //init t
    for(int k = 1; k < (1<<n); k ++){   t[k]  = 1;
        for(int i = 1; i <= n; i ++)
            for(int j = i + 1; j <= n; j ++)
                if(((k & (1<<(i - 1)))!= 0) && ((k & (1<<(j - 1))) != 0)){t[k] *= (long long)((a[i][j] ^ 1) + 1); t[k] %= mod;}
    }
    int summ = t[(1<<n) - 1] - find((1<<(n))-1);//cout<<summ<<endl;
    int tt = summ - finddi((1<<(n)) - 1); if(tt < 0) tt += mod;
    cout<<tt<<endl;
    }
  //  system("pause");
    return 0;
}


hdu5000 clone

证明要用到卷积。。后面这一大段都是copy的话说文章类型怎么没有原创 + copy 这个选项呢。。略纠结。

信号处理中的一个重要运算是卷积.初学卷积的时候,往往是在连续的情形,

  两个函数f(x),g(x)的卷积,是∫f(u)g(x-u)du
  当然,证明卷积的一些性质并不困难,比如交换,结合等等,但是对于卷积运算的来处,初学者就不甚了了。
  
  其实,从离散的情形看卷积,或许更加清楚,
  对于两个序列f[n],g[n],一般可以将其卷积定义为s[x]= ∑f[k]g[x-k]
  
  卷积的一个典型例子,其实就是初中就学过的多项式相乘的运算,
  比如(x*x+3*x+2)(2*x+5)
  一般计算顺序是这样,
  (x*x+3*x+2)(2*x+5)
  = (x*x+3*x+2)*2*x+(x*x+3*x+2)*5
  = 2*x*x*x+3*2*x*x+2*2*x+ 5*x*x+3*5*x+10
  然后合并同类项的系数,
  2 x*x*x
  3*2+1*5 x*x
  2*2+3*5 x
  2*5
  ----------
  2*x*x*x+11*x*x+19*x+10
  
  实际上,从线性代数可以知道,多项式构成一个向量空间,其基底可选为
  {1,x,x*x,x*x*x,...}
  如此,则任何多项式均可与无穷维空间中的一个坐标向量相对应,
  如,(x*x+3*x+2)对应于
  (1 3 2),
  (2*x+5)对应于
  (2,5).
  
  线性空间中没有定义两个向量间的卷积运算,而只有加法,数乘两种运算,而实际上,多项式的乘法,就无法在线性空间中说明.可见线性空间的理论多么局限了.
  但如果按照我们上面对向量卷积的定义来处理坐标向量,
  (1 3 2)*(2 5)
  则有
  2 3 1
  _ _ 2 5
  --------
   
   2
  
  
  2 3 1
  _ 2 5
  -----
    6+5=11
  
  2 3 1
  2 5
  -----
  4+15 =19
  
  
  _ 2 3 1
  2 5
  -------
    10
  
   或者说,
  (1 3 2)*(2 5)=(2 11 19 10)
  
  回到多项式的表示上来,
  (x*x+3*x+2)(2*x+5)= 2*x*x*x+11*x*x+19*x+10
  
  似乎很神奇,结果跟我们用传统办法得到的是完全一样的.
  换句话,多项式相乘,相当于系数向量的卷积.
  
  其实,琢磨一下,道理也很简单,
  卷积运算实际上是分别求 x*x*x,x*x,x,1的系数,也就是说,他把加法和求和杂合在一起做了。(传统的办法是先做乘法,然后在合并同类项的时候才作加法)
  以x*x的系数为例,得到x*x,或者是用x*x乘5,或者是用3x乘2x,也就是
  2 3 1
  _ 2 5
  -----
   6+5=11
  其实,这正是向量的内积.如此则,卷积运算,可以看作是一串内积运算.既然是一串内积运算,则我们可以试图用矩阵表示上述过程。
  
  [ 2 3 1 0 0 0]
  [ 0 2 3 1 0 0]==A
  [ 0 0 2 3 1 0]
  [ 0 0 0 2 3 1]
  
  [0 0 2 5 0 0]' == x
  
  b= Ax=[ 2 11 19 10]'
  
  采用行的观点看Ax,则b的每行都是一个内积。
  A的每一行都是序列[2 3 1]的一个移动位置。
  
  ---------
  
  显然,在这个特定的背景下,我们知道,卷积满足交换,结合等定律,因为,众所周知的,多项式的乘法满足交换律,结合律.在一般情形下,其实也成立.
  
  在这里,我们发现多项式,除了构成特定的线性空间外,基与基之间还存在某种特殊的联系,正是这种联系,给予多项式空间以特殊的性质.
  
  在学向量的时候,一般都会举这个例子,甲有三个苹果,5个橘子,乙有5个苹果,三个橘子,则共有几个苹果,橘子。老师反复告诫,橘子就是橘子,苹果就是苹果,可不能混在一起。所以有(3,5)+(5,3)=(8,8).是的,橘子和苹果无论怎么加,都不会出什么问题的,但是,如果考虑橘子乘橘子,或者橘子乘苹果,这问题就不大容易说清了。
  
  又如复数,如果仅仅定义复数为数对(a,b),仅仅在线性空间的层面看待C2,那就未免太简单了。实际上,只要加上一条(a,b)*(c,d)=(ac-bd,ad+bc)
  则情况马上改观,复变函数的内容多么丰富多彩,是众所周知的。
  
  另外,回想信号处理里面的一条基本定理,频率域的乘积,相当于时域或空域信号的卷积.恰好跟这里的情形完全对等.这后面存在什么样的隐态联系,需要继续参详.
  
  从这里看,高等的卷积运算其实不过是一种初等的运算的抽象而已.中学学过的数学里面,其实还蕴涵着许多高深的内容(比如交换代数)。温故而知新,斯言不谬.
  
  其实这道理一点也不复杂,人类繁衍了多少万年了,但过去n多年,人们只知道男女媾精,乃能繁衍后代。精子,卵子的发现,生殖机制的研究,也就是最近多少年的事情。
  
  孔子说,道在人伦日用中,看来我们应该多用审视的眼光看待周围,乃至自身,才能知其然,而知其所以然。

hdu 4998
就是一道比较简单的数学题, 我就是算出一个点的变化情况然后再带进去求一下, 非常的简单!
老师讲的方法使用矩阵, 一会再写吧。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#define MAXN 100005
using namespace std;
int n, m, k, ans, fat[MAXN], ff[MAXN];
int find(int x){
    if(fat[x] != x){
        int tmp = fat[x];
        fat[x] = find(fat[x]);
        ff[x] = (ff[x] + ff[tmp]) % k;
    }    return fat[x];
}
int main()
{
    scanf("%d%d%d", &n, &m, &k); k ++;
    for(int i = 0; i <= n; i ++)fat[i] = i;
    int c, a, b;
    for(int i = 1; i <= m; i ++){
        scanf("%d%d%d", &c, &a, &b);a --;
        int fa = find(a), fb = find(b);
        if(fa != fb){
            fat[fb] = fa; ff[fb] = (ff[a] - ff[b] + k + c) % k;
        }    
        else if(((ff[b] - ff[a] + k) % k) != c)ans ++;
    }double aa = (double)(m - ans) / (double)m;
    printf("%.5lf\n", aa);
    return 0;
}

hdu5000 clone
以下是fsf的题解。
一个比较显然的事情是显然所有玩意的坐标和是一样的……
然后嘛…………可以证明坐标和=sum{T[i]}/2处的答案最优…………
神奇的方法是…………用卷积证明…………QAQ
首先F(x)是坐标和为x时的答案…………
假设我们处理了前i个坐标…………加入第i+1维坐标就是和一个函数G(x)=[1<=x<=T[i]]卷积嘛…………
首先一个显然的结论是…………一个对称的函数和另一个对称的函数卷积应该还是对称的………………
然后就是显然的单调性啦………………QAQ
嗯就是他说的这样然后就没有了吧
还是我太弱了要不然其实这道题的定义根本就是卷积啊。。
傻逼的我啊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值