Problem:
Problem D: Friday the 13th
Problem
今年も「立命館大学競技プログラミング合宿」が開催されることとなった。僕は毎年開催されるこの合宿をとても楽しみにしている。しかし、欲望に耐え切れず合宿前に散財してしまい、お金に余裕が無くなってしまった。そこで僕は、立命館大学の最寄り駅である南草津まで移動するのに最も安く済む青春18きっぷを使うことにした。この切符は安く済む代わりに乗り換えが多く発生し、移動に丸1日使わなければならないのでとても疲れる。そんな移動をする日が13日の金曜日であることに気づいたのは会津若松駅を出発した後だった。僕は12時間、不安を感じながら電車に揺られるはめになった。
今日は合宿2日目、2015年3月15日、日曜日である。13日は特に何事もなく南草津に到着したが、僕はもうこのような不安を味わいたくないと思った。そこで2日目のジャッジである僕は、指定された期間内に存在する13日の金曜日の数を求める問題を出題し、プログラムを作成してもらうことにした。
閏(うるう)年の定義は以下の通りである。
西暦年が4で割り切れる年は閏年である。
ただし、100で割り切れる年は閏年でない。
ただし、400で割り切れる年は閏年である。
Input
空白で区切られた6つの整数
Y
1
,
M
1
,
D
1
,
Y
2
,
M
2
,
D
2
が1行で与えられる。
Constraints
入力は以下の制約を満たす。
1 ≤
Y
1
≤
Y
2
≤ 10
18
1 ≤
M
i
≤ 12
1 ≤
D
i
≤ 31 (
M
i
= 1, 3, 5, 7, 8, 10, 12)
1 ≤
D
i
≤ 30 (
M
i
= 4, 6, 9, 11)
1 ≤
D
i
≤ 28 (
M
i
= 2 かつ
Y
i
年は閏年でない)
1 ≤
D
i
≤ 29 (
M
i
= 2 かつ
Y
i
年は閏年である)
Y
1
年
M
1
月
D
1
日は
Y
2
年
M
2
月
D
2
日より0日以上前の日付である
Output
Y
1
年
M
1
月
D
1
日から
Y
2
年
M
2
月
D
2
日までの間に存在する13日の金曜日の数を1行に出力せよ。
Sample Input1
2015 3 13 2015 3 13
Sample Output1
1
Sample Input2
2015 2 14 2015 3 15
Sample Output2
1
Sample Input3
1234 5 6 789012345678901234 5 6
Sample Output3
1357101234567708000

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;

    void print();
    template <class t> void print(const vector<t> &);
    template <class t, class u> void print(const pair<t, u> &);
    template <class t> void print(const t&);
    template <class Head, class... Tail> void print(const Head&, const Tail&...);

    template <class t> void println(const vector<vector<t>>&);
    template <class t> void println(const vector<t>&);
    template <class t> void println(const t&);
    template <class Head, class... Tail> void println(const Head&, const Tail&...);
    void println();
    void newline();

    void print(){
        return;
    }

    template <class t>
    void print(const vector<t>&x){
        for(const t&i:x)print(i);
    }
    template <class t, class u>
    void print(const pair<t,u>&p){
        print(p.first);
        print(p.second);
    }
    template <class t>
    void print(const t&x){
        if(was_output)cout<<" ";
        cout<<x;
        was_output = true;
    }
    template <class Head, class... Tail>
    void print(const Head&head,const Tail&...tail){
        print(head);
        print(tail...);
    }

    template<class t>
    void println(const vector<vector<t>>&x){
        for(vector<t> i:x)println(i);
    }
    template<class t>
    void println(const vector<t>&x){
        for(const t&i:x)print(i);
        println();
    }
    template <class t>
    void println(const t&x){
        print(x);
        println();
    }
    void println(){
        if(was_output){
            cout << endl;
            was_output = false;
        }
    }
    template <class Head, class... Tail>
    void println(const Head&head,const Tail&...tail){
        print(head);
        println(tail...);
    }

    void newline(){
        was_output = true;
        println();
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }

    class output_initializer{
    public:
        output_initializer(){
            ios::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << setprecision(20);
        }
    };output_initializer OUTPUT_INITIALIZER_INSTANCE = output_initializer();
}

using namespace templates;

class calendar{
public:
    ll y;
    ll m;
    ll d;
    ll date;
    calendar(ll y,ll m,ll d,ll date):y(y),m(m),d(d),date(date){}
    calendar(ll y,ll m,ll d):y(y),m(m),d(d){
        date = ((-calendar(2015,3,13,0).count_day()+calendar(y,m,d,0).count_day())%7+7)%7;
    }
    calendar next_day(){
        ll ndate = (date + 1) % 7;
        ll nd = d + 1;
        ll nm = m;
        ll ny = y;
        if(is_last_day()){
            nd = 1;
            ++nm;
            if(nm==13){
                ++ny;
                nm = 1;
            }
        }
        return calendar(ny,nm,nd,ndate);
    }

    bool is_uru(){
        return y%400==0 or (y%100 != 0 and y % 4==0);
    }

    bool is_last_day(){
        return d == last_day();
    }

    int last_day(){
        if(set<int>({1,3,5,7,8,10,12}).count(m))return 31;
        if(set<int>({4,6,9,11}).count(m))return 30;
        if(is_uru())return 29;
        return 28;
    }

    bool operator==(calendar other){
        return y == other.y and m == other.m and d == other.d;
    }
    bool operator!=(calendar other){
        return !((*this) == other);
    }

    ll count_day(){
        ll res = ((y-1) / 400) * (400 * 365 + 97) % 7;
        calendar tmp((y-1)/400*400+1,1,1,0);
        while((*this)!=tmp){
            ++res;
            tmp = tmp.next_day();
        }
        return res;
    }
};

ll count_friday(calendar c){
    ll res = 0;
    {
        calendar c4(1,1,1);
        ll add = 0;
        while(c4.y!=401){
            if(c4.date==0 and c4.d==13){
                ++add;
            }
            c4 = c4.next_day();
        }
        res += (c.y-1)/400*add;
    }
    calendar tmp((c.y-1)/400*400+1,1,1);
    while(true){
        if(tmp.date==0 and tmp.d==13){
            ++res;
        }
        if(tmp==c)break;
        tmp = tmp.next_day();
    }
    return res;
}

ll func(){
    ll res = 0;
    {
        ll y = in();
        ll m = in();
        ll d = in();
        res -= count_friday(calendar(y,m,d));
        if(d==13 and calendar(y,m,d).date==0){
            ++res;
        }
    }
    {
        ll y = in();
        ll m = in();
        ll d = in();
        res += count_friday(calendar(y,m,d));
    }
    return res;
}

int main(){
    println(func());
    return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 3404
final_rank: 3

code_snippet: #include<bits/stdc++.h>

#define rep(i,n) for(int i=0;i<(int)n;i++)
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define pb push_back
#define each(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define dbg(x) cerr<<__LINE__<<": "<<#x<<" = "<<(x)<<endl

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pi;
const int inf = (int)1e9;
const double INF = 1e12, EPS = 1e-9;

ll days(ll y, int m, int d){
	if(m < 3) y--, m += 12;
	return 365 * (y % 7) + y / 4 - y / 100 + y / 400 + (153 * m + 8) / 5 + d;
}

int main(){
	ll y, m, d, Y, M, D;
	map<pi, ll> memo, prev;
	
	
	cin >> y >> m >> d >> Y >> M >> D;
	if(d > 13){
		d = 1;
		if(++m > 12) m = 1, y++;
	}
	while(d < 13) d++;
	
	if(D < 13){
		D = 31;
		if(--M < 1) M = 12, Y--;
	}
	while(D > 13) D--;
	
	
	ll ans = 0;
	bool flag = 0;
	while(y < Y || y == Y && m <= M){
		
		if(days(y, m, d) % 7 != 5){
			if(++m > 12) m = 1, y++;
			continue;
		}
		ans++;
		if(!flag && memo.count(pi(y % 2800, m))){
			
			ll dy = y - prev[pi(y % 2800, m)];
			ll da = ans - memo[pi(y % 2800, m)];
			
			ll t = (Y - y) / dy;
			t = max(t - 10, 0ll);
			y += dy * t;
			ans += da * t;
			flag = 1;
		}
		
		memo[pi(y % 2800, m)] = ans;
		prev[pi(y % 2800, m)] = y;
		if(++m > 12) m = 1, y++;
	}
	
	cout << ans << endl;
	
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1796
final_rank: 2

code_snippet: #include<bits/stdc++.h>

#define rep(i,n) for(int i=0;i<(int)n;i++)
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define pb push_back
#define each(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define dbg(x) cerr<<__LINE__<<": "<<#x<<" = "<<(x)<<endl

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pi;
const int inf = (int)1e9;
const double INF = 1e12, EPS = 1e-9;

ll days(ll y, int m, int d){
	if(m < 3) y--, m += 12;
	return 365 * (y % 7) + y / 4 - y / 100 + y / 400 + (153 * m + 8) / 5 + d;
}

int main(){
	ll y, m, d, Y, M, D;
	map<pi, ll> memo, prev;
	
	
	cin >> y >> m >> d >> Y >> M >> D;
	if(d > 13){
		d = 1;
		if(++m > 12) m = 1, y++;
	}
	while(d < 13) d++;
	
	if(D < 13){
		D = 31;
		if(--m < 1) m = 12, y--;
	}
	while(D > 13) D--;
	
	
	ll ans = 0;
	bool flag = 0;
	while(y < Y || y == Y && m <= M){
		
		if(days(y, m, d) % 7 != 5){
			if(++m > 12) m = 1, y++;
			continue;
		}
		ans++;
		if(!flag && memo.count(pi(y % 2800, m))){
			
			ll dy = y - prev[pi(y % 2800, m)];
			ll da = ans - memo[pi(y % 2800, m)];
			
			ll t = (Y - y) / dy;
			t = max(t - 10, 0ll);
			y += dy * t;
			ans += da * t;
			flag = 1;
		}
		
		memo[pi(y % 2800, m)] = ans;
		prev[pi(y % 2800, m)] = y;
		if(++m > 12) m = 1, y++;
	}
	
	cout << ans << endl;
	
	return 0;
}
accuracy: 0.3
time_ms: 10
memory_kb: 1792
final_rank: 4

code_snippet: #include <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
 
using namespace std;
 
#define sz size()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(c) (c).begin(), (c).end()
#define rep(i,a,b) for(long long i=(a);i<(b);++i)
#define clr(a, b) memset((a), (b) ,sizeof(a))
 
#define MOD 1000000007

long long month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

long long checkd(long long y, long long m, long long d){
  if(y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)){
    month[2] = 29;
  }
  else{
    month[2] = 28;
  }
  
  if(m < 1 || m > 12){
    return 0;
  }

  if(d >= 1 && d <= month[m]){
    return 1;
  }

  return 0;
}

long long f(long long y, long long m, long long d){
  long long y1=1;
  long long m1=1;
  long long d1=1;
  long long week=0;
  long long ret = 0;
  long long dd = y/2800;
  y%=2800;
  y+=2800;
  for(;;){
    if(d1==13&&week==4)ret++;
    if(y==y1&&m==m1&&d==d1)break;
    if(checkd(y1,m1,d1)==0){
      if(m1==12){
        y1++;
        m1=1;
        d1=1;
      }
      else{
        m1++;
        d1=1;
      }
      continue;
    }
    else{
      d1++;
      week++;
      week%=7;
    }
  }
  return ret+4816*(dd-1);
}

long long f2(long long y, long long m, long long d){
  long long y1=1;
  long long m1=1;
  long long d1=1;
  long long week=0;
  y%=2800;
  y+=2800;
  for(;;){
    if(y==y1&&m==m1&&d==d1)break;
    if(checkd(y1,m1,d1)==0){
      if(m1==12){
        y1++;
        m1=1;
        d1=1;
      }
      else{
        m1++;
        d1=1;
      }
      continue;
    }
    else{
      d1++;
      week++;
      week%=7;
    }
  }
  return week;
}

int main(){
  long long y1,m1,d1,y2,m2,d2;
  cin>>y1>>m1>>d1>>y2>>m2>>d2;
  long long a = 0;
  if(d1==13&&f2(y1,m1,d1)==4)a=1;
  cout << f(y2,m2,d2)-f(y1,m1,d1)+a << endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1156
final_rank: 1